My Redux state has changed, why doesn’t React trigger a re-render?

You’ve got everything hooked up correctly, but you’re missing one key concept for Redux:

With Redux, you never mutate any part of state.

From the Redux guide:

Things you should never do inside a reducer:

  • Mutate its arguments;
  • Perform side effects like API calls and routing transitions;
  • Call non-pure functions, e.g. Date.now() or Math.random().

In deleteSingleNotification, you’re using .splice to cut the old notification out of your array. Instead, you need to return a brand new array with the unwanted notification missing from it. The easiest way to do this is with the .filter function:

function deleteSingleNotification(notifications, notificationId){
    return notifications.filter (notification => {
        return notification.id !== notificationId
    }
}

Here is a JSBin with your working notification system!


So here is why this works: React-Redux’s job is to update your components whenever a specific part of your Redux store is changed. It uses a === test on every part of the state tree to know if anything changed.

When you go and change the state with something like .splice, it checks and thinks nothing is different.

Here’s an example to demonstrate the problem:

var array = [ 'a', 'b', 'c' ]

var oldArray = array

array.splice (1, 1) // cut out 'b'

oldArray === array // => true!  Both arrays were changed by using .splice,
                   // so React-Redux *doesn't* update anything

Instead, React-Redux needs us to do this:

var array = [ 'a', 'b', 'c' ]

var oldArray = array

array = array.filter (item, index => index !== 1) // new array without 'b'

oldArray === array // false.  That part of your state has changed, so your
                   // componenet is re-rendered

Redux uses this approach for performance reasons. It takes a really long time to loop through a big state tree looking to see if everything is the same. When you keep your tree immutable, only a === test is needed and the process gets much easier.

Leave a Comment