React - Children Components modifying parents state?

Tell us what’s happening:
I want to make sure I understand whats going on here. I understand that state can flow from Parent Components → Child Components when we render child components with state from the parent passed in to the child via props.

BUT, is the reason that a child component can update its parents state because of the binding of the function this.handleChange to this instance of the parent object?

  **Your code so far**

class MyApp extends React.Component {
constructor(props) {
  super(props);
  this.state = {
    inputValue: ''
  }
  /* Is it because of binding that handleChange is pinned to the MyApp object? */
  this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
  this.setState({
    inputValue: event.target.value
  });
}
render() {
  return (
     <div>
      { /* Change code below this line */ }
      <GetInput
      input = {this.state.inputValue} 
      handleChange = {this.handleChange} />
      <RenderInput
      input = {this.state.inputValue} />
      { /* Change code above this line */ }
     </div>
  );
}
};

class GetInput extends React.Component {
constructor(props) {
  super(props);
}
render() {
  return (
    <div>
      <h3>Get Input:</h3>
      <input
        value={this.props.input}
        onChange={this.props.handleChange}/>
    </div>
  );
}
};

class RenderInput extends React.Component {
constructor(props) {
  super(props);
}
render() {
  return (
    <div>
      <h3>Input Render:</h3>
      <p>{this.props.input}</p>
    </div>
  );
}
};
  **Your browser information:**

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0.

Challenge: Pass a Callback as Props

Link to the challenge:

So this is a concept that was a little tricky for me to wrap my head around when I first learned React. The main thing to understand is, a child element doesn’t know anything about its parent element’s state - it is only aware of its own internal state (if any), and props that are passed to it.

What’s actually happening here is that the parent element MyApp has inputValue as an internal state variable, and it has a handleChange callback defined to change that internal state value. Meanwhile, the child element GetInput is receiving that callback as a prop, so it knows to fire that callback prop whenever the input element has an onChange event. But it’s not really the child element that’s changing the parent’s state - it’s the callback function handleChange that is still only defined in the parent component that is causing the parent’s state to change.

It may be a subtle distinction, but think of the relationship this way. Imagine there’s now a child element that has internal state for a counter, BUT the child element sets the initial state of the counter variable based on a PROP it receives from the parent. Now, from the perspective of the parent element, if I pass down a different counter prop to the child, I can effectively change the initial state of the child, so as a parent component, I have ways of directly affecting the state of the child component.

Now in this original situation, let’s say that the parent component stopped passing down the handleChange callback to the child. At that point, there is absolutely nothing the child component can do to “reach into” the parent to affect its state. Any change that had been happening in the parent state was because the parent wanted the child component to trigger some specific callback in the parent component, so the parent ALLOWS this by passing the function down as a prop.

And as a last aside, the binding of the handleChange function doesn’t have anything to do with the parent/child interaction. It’s just to make it so that we bind this to be the MyApp object, so that this.setState inside the handleChange function doesn’t throw an error.

2 Likes

The idea that what is actually changing the parent’s state IS the child element BUT only because the child is given a callback function as a PROP with access to its parents state makes a lot more sense now.

Also, I now understand why the binding of the function has nothing to really do with the Parent/Child interaction.

Your explanation definitely cleared up some of my misconceptions. I appreciate the very thorough response. I think I need to review the this keyword a little more in JavaScript.