Why does the React tutorial recommend that child C

2019-08-02 05:12发布

问题:

According to the React tutorial at https://facebook.github.io/react/tutorial/tutorial.html:

When you want to aggregate data from multiple children or to have two child components communicate with each other, move the state upwards so that it lives in the parent component. The parent can then pass the state back down to the children via props, so that the child components are always in sync with each other and with the parent.

This seems to contradict good OOP practices where each object maintains it own state.

回答1:

When you want to aggregate data from multiple children or to have two child components communicate with each other, move the state upwards so that it lives in the parent component. The parent can then pass the state back down to the children via props, so that the child components are always in sync with each other and with the parent.

Consider a case where a Parent has two children, with a structure as follows

<Parent>
    <Child1/>
    <Child2/>
</Parent>

Now Child1 just has the input component, and Child2 displays what was entered in the input say

In this case if you keep the value of the input in Child1, you cannot access it from the Parent as state is local to a component and is a private property . So it makes sense to keep the property in parent and then pass it down to child as props so that both children can use it

A sample snippet

class Parent extends React.Component {
   constructor(props) {
        super(props);
        this.state = {
             inputVal: ''
        }
   }
   handleChange = (val) => {
        this.setState({inputVal: val});
   }
   render() {
        return (
             <div>
                  <Child1 handleChange={this.handleChange} inpVal={this.state.inputVal}/>
                  <Child2 value={this.state.inputVal}/>
             </div>
        )
   }
}

class Child1 extends React.Component {
   
   render() {
        return (
             <div>
                  <input type="text" value={this.props.inpVal} onChange={(e) => this.props.handleChange(e.target.value)} />
             </div>
        )
   }
}

class Child2 extends React.Component {
   
   render() {
        return (
             <div>
                  {this.props.value}
             </div>
        )
   }
}

ReactDOM.render(<Parent/>, document.getElementById('app'));
<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>
<div id="app"></app>