'How can I pass state to grandparent so that uncle/aunt can use it?

I've been struggling for hours trying to get some code to work. I'm new with React, but I have spent a lot time looking for a solution to this as well, and updating this code as I understood with no success.

Basically my app is a component that splits into two components, with one of those splitting into 9 buttons. When I click one of those buttons, I want its uncle/aunt to recognize that, and use the id of the button that was pushed to create a message.

I figured I should be passing the button id up to the grandparent so that it can pass the id down to the uncle/aunt. But its the passing the id to the grandparent I'm struggling with.

This is the general set up below:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      "x" : " "
    };
  getX(x){
    this.setState({"x": x})
  }
  render() {
    return (
    <div>
      <A getX={this.getX}/>
      <B x={this.state.x} />
    </div>
    )
  }
}


const A = (props) => {
  const getX = (x) => props.getX(x);
  a = [];
  for (let i=0; i<9; i++) {
    a.push(<C id={i} getX={getX}/>);
  return <div>{a}</div>
}


class C extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      "id" : props.id,
      "getX" : (x) => props.getX(x)
    }
    this.handleMouseDown = this.handleMouseDown.bind(this);
  }
  handleMouseDown(e) {
    this.state.getX(e.target.id);
  }
  render() {
    <div />
  }
}


class B extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      "x" : props.x
    }
  }
  render() {
    return <div>{this.state.x}</div>
  }
  
}

Firstly, the getX() method of the App component doesn't seem to be working how I expected it to. By that I mean, when I add getX("7"); to the render method of the App component, just before the return statement, the whole thing crashes. But if I replace this.setState({"x": x}) with this.state.x = x in the getX() method, then the state sucessfully passes down to the component B, which is something at least. But, I don't understand why.

Secondly, I can't work out how to modify the App component's state from within component A. The getX() method of the App component doesn't seem to be passed into component A as I expected. Again, if I insert getX("7"); before the return statement of component A, the whole thing crashes again. I expected the getX function of component A to be the same function as the getX method of the App component, and therefore update the state of the App component. But I've had no success with that at all. I've even tried inserting this.getX = this.getX.bind(this) into the constructor of the App component, but that didn't solve everything for me.

Lastly, as you can probably guess, I cant modify the App component's state from any of the C components.

Any ideas? I'm stumped.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source