0

It is always said that we should not mutate data in the reducer of Redux, or else there could be bugs. For example, we have to do:

    case 'todos/todoToggled': {
      return {
        // Again copy the entire state object
        ...state,
        // This time, we need to make a copy of the old todos array
        todos: state.todos.map(todo => {
          // If this isn't the todo item we're looking for, leave it alone
          if (todo.id !== action.payload) {
            return todo
          }

          // We've found the todo that has to change. Return a copy:
          return {
            ...todo,
            // Flip the completed flag
            completed: !todo.completed
          }
        })
      }
    }

Suppose we don't care about the Undo / Redo capabilities, in which case we have to have all previous states, then on the official docs, it says:

  • It causes bugs, such as the UI not updating properly to show the latest values

Why would UI not update properly? And is this the only bug? (that doc talk about other issue, such as harder to test... but those seem to be not bugs).

This is for deeper understanding of React / Redux.

I think I might have an answer but not entirely sure yet, but I will post 2, 3 days later and compare with other answers.

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • Have you read [this reply](https://github.com/reduxjs/redux/issues/758#issuecomment-141967817) in a similar discussion? If not, might be helpful. Based on that comment, I *guess* the main reason is, redux updates only what is necessary, and if you change your state elsewhere, redux might not process that as a change. – Sinan Yaman Mar 29 '21 at 12:58
  • Does this answer your question? [Redux: Why is avoiding mutations such a fundamental part of using it?](https://stackoverflow.com/questions/37531909/redux-why-is-avoiding-mutations-such-a-fundamental-part-of-using-it) – jonrsharpe Mar 29 '21 at 13:02
  • Also e.g. https://stackoverflow.com/q/48806986/3001761, https://stackoverflow.com/q/39343700/3001761 – jonrsharpe Mar 29 '21 at 13:04

1 Answers1

2

Because React-Redux depends on reference equality checks to determine if state has changed and a component should re-render.

For more details, see my extensive post The History and Implementation of React-Redux , which covers all you need to know about the internals of React-Redux and why it works the way it does.

markerikson
  • 63,178
  • 10
  • 141
  • 157
  • yes, this is what I found out about `setData()` which is from a `useState()` hook. If I use `arr[i + 1] = someItem; setData(arr);`, then it thinks `arr` is the same thing, and if I have other state, such as `pageMax` or whatever, that ones triggers an update by the user clicking on a button, but `setData(arr)` which is a `fetch()` success handler does not trigger an update, so the page is always "one step" behind what should be displayed. – nonopolarity Mar 29 '21 at 19:43
  • 1
    Yes, [React also relies on immutable updates for the state hooks as well](https://blog.isquaredsoftware.com/2020/05/blogged-answers-a-mostly-complete-guide-to-react-rendering-behavior/#immutability-and-rerendering). – markerikson Mar 29 '21 at 19:53
  • if it is front end and the data array is just 500 items or 1000 items or less (even points on a chart), I think creating a new array is ok. But I also wonder what if we can use `setData(arr, { forceUpdate: true })` so that we don't have to make a copy of the array. (but React has to have the mechanism so that a flag can trigger an update) – nonopolarity Mar 30 '21 at 05:53
  • Nope, that's not how React works, by design. – markerikson Mar 30 '21 at 14:25