简体   繁体   中英

Re-render does not occur when state changes

I have the following component...

class App extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
        register: false
    }

  }
  handleClick(event)
    {
      console.log("link was clicked");
      this.setState({register: true});

    }

    render(){


        return (

            <If condition={ this.state.register }>
                <Then><Register /></Then>
                <Else>{() => 
                    <Index event={this.handleClick} />

                }</Else>
            </If>   
        );  
    }
}

module.exports = App;

So my function handleClick is called whenever a link is clicked, this changes the state to true. However, the <IF> statement does not notice that state changed and so remains the same (only Index remains)

What I want is for <Register /> to be rendered whenever the link is clicked. So if the link is clicked, the state will change to true, and then the IF statement will catch this change and render the right component.

How can I do this? How can I get the IF statement to notice the change in state?

Not sure what <Index> is or what is it doing with event . If it just calls the function that is passed as props.event , the handleClick function is called with the wrong this reference and doesn't set the state for the correct component.

If you're using Babel with stage-2 preset or lower, you can use syntax to bind this :

class App ... {
  ...
  handleClick = (event) => { ... }
  ...
}

Yes, it's an arrow function definiton, but directly inside class . It will bind the correct this reference so it can be passed around and it will have proper this reference when called.

Alternatively, you can use bind directly when passing the function, as event={this.handleClick.bind(this)} . But beware, this creates a new function every time it's called, so it might impact performance if it's called very often. It's advised that you do not use this approach and airbnb's eslint config will mark this as an error. A better approach would be to do one time binding inside the constructor, as this.handleClick= this.handleClick.bind(this) .

If you wish to know more, this Medium post covers 2 more ways to bind and explains all 5 options.

you can do it by following code,

   return (
      { this.state.register ? <Register /> : <Index event={this.handleClick.bind(this)} /> }
    );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM