Bolboa Bolboa - 1 year ago 39
Javascript Question

Re-render does not occur when state changes

I have the following component...

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

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



return (

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


module.exports = App;

So my function
is called whenever a link is clicked, this changes the state to true. However, the
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
statement to notice the change in state?

Answer Source

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.