Search code examples
reactjsreduxreact-reduxfrontendreselect

Implementing reselect in redux prevents new changes to appear instantly


In my React project, I have implemented memoization using reselect library. The state basically has a list of objects which I render as cards.

Before implementing reselect, whenever I added a new element, the change instantly showed up and a new card got added at the end. However, now when I add a new element it does not instantly shows up, but rather shows up when the page is reloaded.

Why does this happen? And is there a way to fix this without removing the use of reselect library

EDIT : The issue has been solved, and as pointed out in the answers it was because I was simply mutating the state

The earlier code was as follows

case IssueActionTypes.ADD_ISSUE:
        state.issueList.push(action.payload)
        return {
            ...state
        }

which I replaced with

case IssueActionTypes.ADD_ISSUE:
        return {
            ...state,
            issueList : [...state.issueList, action.payload]
        }

which fixed the issue


Solution

  • Most likely you are returning mutated state in your reducers instead of returning a new array.

    Docs:

    createSelector uses an identity check (===) to detect that an input has changed, so mutating an existing object will not trigger the selector to recompute because mutating an object does not change its identity. Note that if you are using Redux, mutating the state object is almost certainly a mistake.

    Example of returning mutated state (from docs):

    export default function todos(state = initialState, action) {
      switch (action.type) {
      case COMPLETE_ALL:
        const areAllMarked = state.every(todo => todo.completed)
        // BAD: mutating an existing object
        return state.map(todo => {
          todo.completed = !areAllMarked
          return todo
        })
    
      default:
        return state
      }
    }