Skip to content Skip to sidebar Skip to footer

In Which Order Are Parent-child Components Rendered?

If I have Two Components (Parent & Child) like this : 1-The Parent (Countdown): var Countdown = React.createClass({ getInitialState: function(){ return{count: 0}; },

Solution 1:

I'm not immediately seeing a clear "this is the order of lifecycle events between parent and child" in the React docs, though I could be missing it.

It's trivial to determine empirically, of course:

classChildextendsReact.Component {
    constructor(...args) {
        super(...args);
        console.log("Child constructor");
    }
    componentWillMount(...args) {
        console.log("Child componentWillMount");
    }
    componentDidMount(...args) {
        console.log("Child componentDidMount");
    }
    render() {
        console.log("Child render");
        return<div>Hi there</div>;
    }
}

classParentextendsReact.Component {
    constructor(...args) {
        super(...args);
        console.log("Parent constructor");
    }
    componentWillMount(...args) {
        console.log("Parent componentWillMount");
    }
    componentDidMount(...args) {
        console.log("Parent componentDidMount");
    }
    render() {
        console.log("Parent render start");
        const c = <Child />;
        console.log("Parent render end");
        return c;
    }
}

ReactDOM.render(<Parent />, document.getElementById("react"));
.as-console-wrapper {
  max-height: 100%!important;
}
<divid="react"></div><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

That shows us the order:

Parent constructor
Parent componentWillMount
Parent render start
Parent render end
Child constructor
Child componentWillMount
Child render
Child componentDidMount
Parent componentDidMount

Which got me wondering about the order of children within a parent, so:

classChildextendsReact.Component {
    constructor(props, ...rest) {
        super(props, ...rest);
        console.log(this.props.name + " constructor");
    }
    componentWillMount(...args) {
        console.log(this.props.name + " componentWillMount");
    }
    componentDidMount(...args) {
        console.log(this.props.name + " componentDidMount");
    }
    render() {
        console.log(this.props.name + " render");
        return<div>Hi from {this.props.name}!</div>;
    }
}

classParentextendsReact.Component {
    constructor(...args) {
        super(...args);
        console.log("Parent constructor");
    }
    componentWillMount(...args) {
        console.log("Parent componentWillMount");
    }
    componentDidMount(...args) {
        console.log("Parent componentDidMount");
    }
    render() {
        console.log("Parent render start");
        const result =
            <div><Childname="Child1" /><Childname="Child2" /></div>;
        console.log("Parent render end");
        return result;
    }
}

ReactDOM.render(<Parent />, document.getElementById("react"));
.as-console-wrapper {
  max-height: 100%!important;
}
<divid="react"></div><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Which gives us:

Parent constructor
Parent componentWillMount
Parent render start
Parent render end
Child1 constructor
Child1 componentWillMount
Child1 render
Child2 constructor
Child2 componentWillMount
Child2 render
Child1 componentDidMount
Child2 componentDidMount
Parent componentDidMount

Not at all surprising, but good to double-check. :-)

Solution 2:

Just adding componentWillUnmount to the cycle:

classChildextendsReact.Component {
    constructor(props, ...rest) {
        super(props, ...rest);
        console.log(this.props.name + " constructor");
    }
    componentWillMount(...args) {
        console.log(this.props.name + " componentWillMount");
    }
    componentWillUnmount(...args) {
        console.log(this.props.name + " componentWillUnmount");
    }
    componentDidMount(...args) {
        console.log(this.props.name + " componentDidMount");
    }
    render() {
        console.log(this.props.name + " render");
        return<div>Hi from {this.props.name}!</div>;
    }
}

classParentextendsReact.Component {
    constructor(...args) {
        super(...args);
        console.log("Parent constructor");
    }
    componentWillMount(...args) {
        console.log("Parent componentWillMount");
    }
    componentWillUnmount(...args) {
        console.log("Parent componentWillUnmount");
    }
    componentDidMount(...args) {
        console.log("Parent componentDidMount");
    }
    render() {
        console.log("Parent render start");
        const result =
            <div><Childname="Child1" /><Childname="Child2" /></div>;
        console.log("Parent render end");
        return result;
    }
}

classParentWrapperextendsReact.Component {
    constructor(...args) {
        super(...args);
        this.state = { showParent: true };
        setTimeout(() => { this.setState({ showParent: false }) });
    }
    render() {
        return<div>{this.state.showParent ? <Parent /> : ''}</div>;
    }
}

ReactDOM.render(<ParentWrapper />, document.getElementById("react"));
.as-console-wrapper {
  max-height: 100%!important;
}
<divid="react"></div><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

result :

Parent constructor
Parent componentWillMount
Parent render start
Parent render end
Child1 constructor
Child1 componentWillMount
Child1 render
Child2 constructor
Child2 componentWillMount
Child2 render
Child1 componentDidMount
Child2 componentDidMount
Parent componentDidMount
Parent componentWillUnmount
Child1 componentWillUnmount
Child2 componentWillUnmount

Solution 3:

a live demo

react-parent-child-lifecycle-order

https://33qrr.csb.app/

https://codesandbox.io/s/react-parent-child-lifecycle-order-33qrr

create order


parent constructor
parent WillMount
parent render

child constructor
child WillMount
child render
child DidMount

parent DidMount

destroy order

parent WillUnmount

child WillUnmount

// child unmount// parent unmount

Solution 4:

The render order is executed in the order of the react component tree, however, the mount order is in the reverse order (with the inner-most child component mounting first.)

Solution 5:

It is possible to make the parent's ComponentDidMount method execute before the child's ComponentDidMount method. And here is how it is done.

Inside the first div in the parent, before anything is rendered, check if state is set yet. Only render anything if state is set.

Example:

render() {
  const { t } = this.props;
  return (
    <div>
      {this.state.row !== null ? (
            ...
      ) : null}
    </div>
  );
}

Post a Comment for "In Which Order Are Parent-child Components Rendered?"