user2519193
user2519193

Reputation: 211

In ReactJS, How do I update child states from parent class?

Here is the parent class

class Root extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        word: Words,
    };
}

changeTheWord(i) {
    this.state.word.changeWord(i);
}

render() {
    return (
        <div className="game">
            <ul>
                <li><a href="#" onClick={() => this.changeTheWord('hey')}>Home</a></li>
                <li><a href="">News</a></li>
                <li><a href="">Contact</a></li>
                <li><a href="">About</a></li>
            </ul>

            <this.state.word />
        </div>
    );
}
}

And here is the child class

class Words extends React.Component {
constructor(props) {
    super(props)
    this.state = {
        data: "read"
    }
}

changeWord(i) {
    this.state.data = i;
}

render() {
    var sentence = "testing";
    if (this.state.data != null) {
        sentence = this.state.data;
    }
    return (
        <div class="center">
            <div class="words">

                <p>{sentence}</p>


            </div>
        </div>
    );
}
}

What I am trying to do, is call the child's changeWord method from the parent class Root, but for some reason it doesn't work and React gives me an error, TypeError: this.state.word.changeWord is not a function.

This it the line responsible for calling the function

<li><a href="#"onClick={ () => this.changeTheWord('hey')}>Home</a></li>

How do I approach this problem?

Upvotes: 1

Views: 60

Answers (2)

devserkan
devserkan

Reputation: 17638

You are using React's logic somehow wrong. Why do you want to keep a whole React component (child here) in your state and mutate it with complex and confusing methods? React's logic is very simple and clean. Use state and props, render child components and pass those to it where necessary. Before going any further I strongly suggest reading the basic documentation.

Probably you want to do something like this.

class Parent extends React.Component {
  constructor( props ) {
    super( props );
    this.state = {
      data: "default sentence",
    };
  }

  changeTheWord = ( i ) => {
    this.setState( { data: i } );
  }

  render() {
    return (
      <div className="game">
        <Child sentence={this.state.data} changeTheWord={this.changeTheWord} />
      </div>
    );
  }
}

const Child = props => (
  <div>
    <ul>
      <li>
        <a href="#" onClick={() => props.changeTheWord( "hey" )}>
          Home
        </a>
      </li>
      <li>
        <a href="">News</a>
      </li>
      <li>
        <a href="">Contact</a>
      </li>
      <li>
        <a href="">About</a>
      </li>
    </ul>
    {props.sentence}
  </div>
);

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

Upvotes: 2

Trent
Trent

Reputation: 4316

In your example, the word state property is initialized with the class Words, not an instance of it.

Instead, try initializing your state as follows:

this.state = {
  word: new Words()
}

Upvotes: 0

Related Questions