NextProps are always identical to this.props in WillReceiveProps components, even when the props have changed

I have a component in a React application that displays a common value to the user. When this value rises, I want to make noise. I realized that in a component that displays the total, would be a good place to reproduce this noise.

So, I added the componentWillReceiveProps method to the component, and in it I calculate two totals: total calculated from this.props and nextTotal calculated from nextProps .

To my surprise, even when the values ​​change and the total values ​​change, nextTotal and total always the same. Thus, the conditional that I want to shoot when the total is no good will never happen.

I wrote a simple one-component example. JSfiddle .

 var Hello = React.createClass({ componentWillReceiveProps: function(nextProps) { var total = 0; this.props.vals.forEach(val => total+= val); var nextTotal = 0; nextProps.vals.forEach(val => nextTotal+= val); console.log(total, nextTotal) if (nextTotal > total) { //never runs console.log('moving up'); } }, render: function() { var total = 0; vals.forEach(val => total+= val) return ( <div>{total}</div> ) } }); var vals = [1, 21, 452, 123]; setInterval(renderReact, 1000) function renderReact() { vals.push(10); ReactDOM.render( <Hello vals={vals} />, document.getElementById('container') ); } 

As you can see, every second it adds 10 to the vals array, which means that the total number moves up by 1. But if you open the console, you will see that total and nextTotal always the same, and moving up never registered.

I am clearly misunderstanding something, and if anyone can explain what my misunderstanding is, and how I should achieve what I'm going to, it would be fantastic.

+6
source share
1 answer

As noted in the comments (by @PitaJ), your problem is that you are passing the array for the first time, and then ALTERING array - instead of calling with a new property. You have reached the object where your component contains the link as an existing property and changed its contents.

In your script, try the following:

 function renderReact() { vals.push(10); ReactDOM.render( <Hello vals={vals.concat([])} />, document.getElementById('container') ); } 

Passing a copy of the array as a support each time, you will see that they are different from each other.

This is actually a non-trivial source of errors when using the reaction and can occur even when using the abbreviation with it if the reducers were not carefully written. Using immutable data structures is one way to avoid this.

+10
source

All Articles