Jessie Richardson Jessie Richardson - 3 months ago 11
React JSX Question

Stuck on Child Component Communicating to Parent Reactjs

I am super stuck on something. While I understand how a parent can pass props down to a child, I can't figure out how to use a child to communicate back up to a parent, grandparent, etc.

Basically, I have a child that is a nested component, and I want to make it so that, upon a click of this child component, another child is rendered at the same level as parent.

Here is my code...

var Grandparent = React.createClass({
getInitialState: function() {
return {closed: true};
},
checkMenuState: function() {
if (this.state.closed == true) {
return;
}
else {
return <Child/>;
}
},
handleState: function() {
this.setState({closed: false});
{this.checkMenuState}
},
render: function() {
return <div><Parent/>{this.checkMenuState()}<OtherChild onClick={this.handleState}/></div>
}
})

var Parent = React.createClass({
render: function() {
var parentSquare={backgroundColor: 'blue', height: 400, width: 400};
return <div style={parentSquare}></div>;
}
});

var Child = React.createClass({
render: function() {
var childSquare={backgroundColor: 'orange', height: 100, width: 100, top: 0, position: 'absolute'};
return <div style={childSquare} closed={this.props.closed}></div>
}
});

var OtherChild = React.createClass({
render: function() {
var childSquare={backgroundColor: 'yellow', height: 100, width: 100, top: 100, position: 'absolute'};
return <div style={childSquare}></div>
}
});

ReactDOM.render(
<Grandparent/>,
document.getElementById('container')
);


So upon initial rendering, the page should look like this:Iinitial rendering

And then, once the yellow div is clicked, it should look like this:

Rendering after yellow div onClick

As of right now, nothing is happening when I click. Here is a link to my JSFiddle:
JSFiddle

Answer

In order to allow your children to modify its parent's state you should pass a closure (a method with access to another scope) from the parent to the children. Notice that your so called "parent" is not a real parent ( :'( ) but a sibling of your child components. Only the Grandparent has inner components.

var Grandparent = React.createClass({
  getInitialState: function() {
    return { showChild: false }
  },


  displayChild: function() {
    this.setState({ showChild: true })
  },

  render: function() {
    return <div>
      <Parent />
      { this.state.showChild ? <Child /> : undefined }
      <OtherChild onClick={ this.displayChild } />
    </div>
  }
})

var Parent = React.createClass({
  render: function() {
    var parentSquare = {
      backgroundColor: 'blue',
      height: 400,
      width: 400
    }

    return <div style={ parentSquare }></div>
  }
})

var Child = React.createClass({
  render: function() {
    var childSquare = {
      backgroundColor: 'orange',
      height: 100,
      width: 100,
      top: 0,
      position: 'absolute'
    }

    return <div style={ childSquare }></div>
  }
})

var OtherChild = React.createClass({
  render: function() {
    var childSquare = {
      backgroundColor: 'yellow',
      height: 100,
      width: 100,
      top: 100,
      position: 'absolute'
    }

    return <div style={ childSquare } onClick={ this.props.onClick }></div>
  }
})

ReactDOM.render(
  <Grandparent/>,
  document.getElementById('container')
)

Give it a try!

Comments