Reactjs 反应嵌套组件的渲染方法的顺序以及它如何与Redux一起工作

Reactjs 反应嵌套组件的渲染方法的顺序以及它如何与Redux一起工作,reactjs,react-redux,Reactjs,React Redux,我正在做一个在页面上显示课程的项目。为了获取课程,我使用redux存储获取的课程。以下是主要课程页面: Course.js: class Course extends Component{ constructor(props){ super(props); this.state = { id: "", } } render() { return( <Co

我正在做一个在页面上显示课程的项目。为了获取课程,我使用redux存储获取的课程。以下是主要课程页面:

Course.js:

class Course extends Component{
    constructor(props){
        super(props);
        this.state = {
            id: "",
        }
    }

    render() {
        return(
            <CourseWrapper>
                {/* <Fragment> */}
                    <div className={"test"}>
                        {console.log(store.getState()),
                        this.props.currentCourse.length < 1 ? null : this.props.currentCourse[0]["units"]}
                    </div>
                        <Dashboard />
                    <div>
                        {}
                    </div>        
                {/* </Fragment> */}
            </CourseWrapper>
        );
    }
}

const mapStateToProps = state => {
    return{
        currentCourse: state.courses.currentCourse,
    }
}
课程扩展组件{
建造师(道具){
超级(道具);
此.state={
id:“”,
}
}
render(){
返回(
{/*  */}
{console.log(store.getState()),
this.props.currentCourse.length<1?null:this.props.currentCourse[0][“单位”]}
{}
{/*  */}
);
}
}
常量mapStateToProps=状态=>{
返回{
currentCourse:state.courses.currentCourse,
}
}
我在CourseWrapper组件的构造函数中发出“getCourse()”操作

CourseWrapper.js:

class CourseWrapper extends React.Component{

    constructor(props){
        super(props);  
        console.log("wrapper")
        this.props.getCourseTest("noUse");
    }

    render(){    
        return(
            <div>
                {console.log(this.props.children),
                this.props.children}
            </div>
        )
    }
}

const mapDispatchToProps = dispatch =>{
    return {
        getCourseTest: noUse => dispatch(getCourse(noUse)),
    }
}

export default connect(null,mapDispatchToProps)(CourseWrapper);
class CourseWrapper扩展了React.Component{
建造师(道具){
超级(道具);
log(“包装器”)
这个.props.getCourseTest(“noUse”);
}
render(){
返回(
{console.log(this.props.children),
这个.道具.儿童}
)
}
}
const mapDispatchToProps=调度=>{
返回{
getCourseTest:noUse=>dispatch(getCourse(noUse)),
}
}
导出默认连接(null,mapDispatchToProps)(CourseWrapper);
当我检查console.log时,我发现1。第一个日志显示的是没有课程的商店的初始状态,然后是2。CourseWrapper.js构造函数中的“wrapper”,然后是3。由包装的孩子,最后是4。store.getStore()'下再次包含预期的课程对象


我的问题是:为什么第一个日志是存储的初始状态而不是“包装器”?而且里面没有课程obj。这引出了下一个问题,我认为首先调用CourseWrapper的构造函数,它分派'getCourse'操作,然后它的子对象被呈现。但是,日志显示{console.log(store.getState())首先调用,CourseWrapper不是首先呈现的吗?或者我对呈现实际上如何安排嵌套组件有一些误解

不,在呈现之前,组件应该获取其子级,您甚至可以在父级构造函数的props.children中找到它们。所以子级JSX对象的属性应该首先计算

  • 将计算console.log(store.getState()),因为它位于div JSX内部
  • CourseWrapper构造函数调用并作为子级获取div
  • CourseWrapper的render函数调用
  • 如果CourseWrapper呈现任何其他组件-其构造函数和呈现函数调用
  • setState
    的调用是异步的-不要依赖此.state立即反映新值

  • CourseWrapper
    课程中使用
    这意味着
    CourseWrapper
    课程中构建。呈现…和
  • render
    实际上并不呈现任何内容,它构造了一个描述,描述了React稍后应该呈现的内容

    render() {
      return(
        create_node(CourseWrapper,
          ...
          create_node(div,
            ...
            console.log(store.getState()),
            ...
          )
        )
      )
    }
    
    因此,正如您所看到的,在
    Course.render
    中调用了
    console.log(store.getState())
    ,然后在
    create\u节点的某个地方调用了
    newcoursewrapper
    ,然后是
    CourseWrapper.render
    ,只有
    console.log(“wrapper”)

    (不要将其视为实际的React算法,这只是一个过于简单的原则)

  • 然后遵循相同的想法:
    …好的,
    很难调用CourseWrapper的子级…让我们假设
    CourseWrapper.render
    如下所示

    render(){    
        return(
            <div>
                <SomeChild/>
                {this.props.children}
            </div>
        )
    }
    
    render(){
    返回(
    {this.props.children}
    )
    }
    
    然后,SomeChild是
    CourseWrapper
    的子对象,而
    this.props.children
    也是它的子对象,但是
    this.props.children
    课程
    之前就已经在
    CourseWrapper
    内部创建了
    SomeChild


  • 我明白了。有解决办法吗?我的想法是,我不使用“props.childern”,而是将所有这些实际内容放在CourseWrapper类中,以便它遵循order@HanayoZz,没关系,如果没有必要,您不需要使用children,我只是告诉您,在初始化组件之前,它应该获得属性,以及您将其包装在属性子对象中。在调用render()时,通常无法初始化该属性子对象,然后才能让属性子对象进行双重检查,首先呈现的元素是外部标记中的子元素,而不是那些外部标记本身。对吗?@HanayoZz,我不够准确,现在我会修正我的答案。我发现Babel编译器实际上帮助我理解它们是如何呈现的。这种翻译非常有帮助!在我看来,它是以console.log的方式编译的首先执行(store.getState()),然后创建_节点(div,最后是包装器)。如果我错了,请纠正我。