父子组件呈现的顺序是什么?

时间:2017-06-20 13:50:28

标签: javascript html reactjs dom jsx

如果我有这样的两个组件(父母和孩子):

1 - 家长(倒计时):

var Countdown = React.createClass({
  getInitialState: function(){
    return{count: 0};
  },
  handleSetCountdown: function(seconds){
    this.setState({
      count: seconds
    });
  },
  render:function(){
    var {count} = this.state;
    return(
      <div>
        <Clock totalSeconds={count}/>
        <CountdownForm onSetCountdown={this.handleSetCountdown} />
      </div>
    );
  }
});

module.exports =Countdown;

2-Child(CountdownForm):

var CountdownForm = React.createClass({
  onSubmit: function(e){
    e.preventDefault();
    var strSeconds = this.refs.seconds.value;
    if(strSeconds.match(/^[0-9]*$/)){
      this.refs.seconds.value ='';
      this.props.onSetCountdown(parseInt(strSeconds,10));

    }
  },
  render: function(){
    return(
      <div>
        <form ref="form" onSubmit={this.onSubmit} className="countdown-form">
          <input type="text" ref="seconds" placeholder="Enter Time In Seconds"/>
          <button className="button expanded">Start</button>
        </form>
      </div>
    );
  }
});

module.exports = CountdownForm;

我对生命周期(组件的渲染顺序)感到困惑?

4 个答案:

答案 0 :(得分:13)

我没有立即看到明确的&#34;这是父母和孩子之间生命周期事件的顺序&#34;在React文档中,虽然我可能会错过它。

当然,凭经验确定是微不足道的:

&#13;
&#13;
class Child extends React.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>;
    }
}

class Parent extends React.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"));
&#13;
.as-console-wrapper {
  max-height: 100% !important;
}
&#13;
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
&#13;
&#13;
&#13;

这向我们展示了订单:

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

让我想知道父母中孩子的顺序,所以:

&#13;
&#13;
class Child extends React.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>;
    }
}

class Parent extends React.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>
                <Child name="Child1" />
                <Child name="Child2" />
            </div>;
        console.log("Parent render end");
        return result;
    }
}

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

这给了我们:

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

一点也不奇怪,但要仔细检查。 : - )

答案 1 :(得分:3)

只需将componentWillUnmount添加到循环中即可:

class Child extends React.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>;
    }
}

class Parent extends React.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>
                <Child name="Child1" />
                <Child name="Child2" />
            </div>;
        console.log("Parent render end");
        return result;
    }
}

class ParentWrapper extends React.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;
}
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

结果:

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

答案 2 :(得分:1)

现场演示

react-parent-child-lifecycle-order

https://33qrr.csb.app/

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

创建订单


parent constructor
parent WillMount
parent render

child constructor
child WillMount
child render
child DidMount

parent DidMount

销毁订单

parent WillUnmount

child WillUnmount

// child unmount

// parent unmount



答案 3 :(得分:0)

渲染顺序是按照react组件树的顺序执行的,但是挂载顺序是相反的顺序(最里面的子组件挂载)首先。)