Optimize Re-Renders with shouldComponentUpdate

Tell us what’s happening:

I’m getting this message but I’m not sure why:

OnlyEvens should re-render only when nextProps.value is even.

Thought using modulo would do this, what am I missing?

Your code so far


class OnlyEvens extends React.Component {
  constructor(props) {
    super(props);
  }
  shouldComponentUpdate(nextProps, nextState) {
    console.log('Should I update?');
     // change code below this line
     if (nextState % 2 == 0){
    return true;
     }
     // change code above this line
  }
  componentWillReceiveProps(nextProps) {
    console.log('Receiving new props...');
  }
  componentDidUpdate() {
    console.log('Component re-rendered.');
  }
  render() {
    return <h1>{this.props.value}</h1>
  }
};

class Controller extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0
    };
    this.addValue = this.addValue.bind(this);
  }
  addValue() {
    this.setState({
      value: this.state.value + 1
    });
  }
  render() {
    return (
      <div>
        <button onClick={this.addValue}>Add</button>
        <OnlyEvens value={this.state.value}/>
      </div>
    );
  }
};

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/front-end-libraries/react/optimize-re-renders-with-shouldcomponentupdate

2 Likes

If you take a look at your question:

and then your code:

then you might able to see one problem. You are also going to a return false if the component should not render.

Hope this helps without just giving you the answer :slight_smile:

1 Like

ok thanks got it now, this is working:

if (nextProps.value % 2 == 0){
    return true;
     }

So obvious now I’ve got it!

it passes with and without adding in the else btw but maybe best to keep it in for clarity

Cheers for the help :slight_smile:

If you want to use even less lines of code, you could also do:

return nextProps.value  % 2 == 0;
3 Likes

Hey, I have completed the challenge long back without any help but I forgot the solution.

Anyhow my question is, the above solution solves the challenge but when you close the popup and try clicking the add button it completely disappears.

If I am not wrong clicking the button should show 2, 4, 8…

It does this for me to, but it also does it for the default code.

The button and 0 disappear for me after I click ‘Add’. Shouldn’t I see 2,4,6, etc ?
I disabled the popup blockers and restarted the chrome browser. I even tried it on my IE. Hmm.

Same for me have you gotten any updates on this? The html just disappears for me.

Correct, i pass the test but cant actually see results. I’m assuming the first result is 1 which would be false here so it doesnt render anything for some reason.


> class OnlyEvens extends React.Component {
>   constructor(props) {
>     super(props);
>   }
>   shouldComponentUpdate(nextProps, nextState) {
>     console.log('Should I update?');
>      // change code below this line
>     return true;
>      // change code above this line
>   }
>   componentWillReceiveProps(nextProps) {
>     console.log('Receiving new props...');
>   }
>   componentDidUpdate() {
>     console.log('Component re-rendered.');
>   }
>   render() {
>     return <h1>{this.props.value}</h1>
>   }
> };
> 
> class Controller extends React.Component {
>   constructor(props) {
>     super(props);
>     this.state = {
>       value: 0
>     };
>     this.addValue = this.addValue.bind(this);
>   }
>   addValue() {
>     this.setState({
>       value: this.state.value + 1
>     });
>   }
>   render() {
>     return (
>       <div>
>         <button onClick={this.addValue}>Add</button>
>         <OnlyEvens value={this.state.value}/>
>       </div>
>     );
>   }
> };

Yes i am using Chrome.

I actually pasted the wrong code here is the correct code i used sorry.

class OnlyEvens extends React.Component {
  constructor(props) {
    super(props);
  }
  shouldComponentUpdate(nextProps, nextState) {
    console.log('Should I update?');
     // change code below this line
   if(nextProps.value % 2 === 0){
     return true;
   }
   return false;
     // change code above this line
  }
  componentWillReceiveProps(nextProps) {
    console.log('Receiving new props...');
  }
  componentDidUpdate() {
    console.log('Component re-rendered.');
  }
  render() {
    return <h1>{this.props.value}</h1>
  }
};

class Controller extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 0
    };
    this.addValue = this.addValue.bind(this);
  }
  addValue() {
    this.setState({
      value: this.state.value + 1
    });
  }
  render() {
    return (
      <div>
        <button onClick={this.addValue}>Add</button>
        <OnlyEvens value={this.state.value}/>
      </div>
    );
  }
};

I think cleaner code can be written with this:

shouldComponentUpdate(nextProps, nextState) {
    console.log('Should I update?');
     // change code below this line
    return nextProps.value % 2 === 0;
     // change code above this line
  }

Now realized, @oliverdudman already showed this approach.

Just passed this test with the modulo operator, no problem.

But since the instructions said to compare this.props with nextProps, and the increment is by 1 each click, I thought this logic would also work:

if (nextProps.value - this.props.value == 2) return true;
else return false;

But it doesn’t. Can someone point out the flaw of my logic?

Why does this work? Isn’t shouldComponentUpdate looking for a boolean value?

Wait! I get it. I get it. A true equation is the same as saying “True”. If I wrote 2=2 that would be the same as writing True