Why do Redux examples pass an empty object as the first argument to Object.assign ()?

In the todoMVC example of a redux project, the todos reducer has the following lines:

export default function todos(state = initialState, action){ ... case EDIT_TODO: return state.map(todo => todo.id === action.id ? Object.assign({}, todo, { text: action.text }) : todo ) } 

This piece of code is related to updating a specific todo object. My question here is that since state.map () will always return a new array. Then you need to do the following:

 Object.assign({}, todo, { text: action.text}) 

Could it be:

 Object.assign(todo, { text: action.text}) 

UPDATE

I understand the difference between Object.assign({}, blah...) vs Object.assign(obj, blah...) . Let me rephrase my question:

Redux wants reducers to return a new state instead of mutating an existing state. I understood. In my example, I have an array of objects. I want to change the order of the first two elements. Check out the jsbin example here .

  • Since Array.map always returns a new array , the reference to the returned gurranteed array will be new. Check it out.
  • However, the elements in the returned array are not all new . The reference to the first two elements is new. However, the third element is not. This is the same third element as in the old array.

So my question is about the third element, should I use:

Object.assign({}, third_element) or just return the third_elment

Does Redux require a new array with new references to every object inside it (even if the values ​​stored in these new objects are identical to the old objects) or just a new array with updated new elements?

+7
javascript reactjs redux
source share
3 answers

Tweet from Dan Abramov (creator of Redux):

The general misconception of Redux: you need to deeply clone a state. Reality: if something inside does not change, save your link in the same way!

https://twitter.com/dan_abramov/status/688087202312491008

+4
source share

This is the nature of the operation of Object.assign . It returns the target as the return value of its operation. So, in the first syntax:

 Object.assign({}, todo, { text: action.text}) 

you create a completely new object with the enumerated properties todo and { text: action.text} .

If you do this:

 Object.assign(todo, { text: action.text}) 

Then todo itself is the target, so it will be mutated, and that will be what is returned from Object.assign .

The first method makes the mapping operation completely unchanged, creating a new array of completely new objects.

Here is jsbin that illustrates what I mean. Note that in the first example, the original object in the array has changed, which means that the state has been mutated. In the second, the original object remains the same:

https://jsbin.com/boxeserave/edit?html,js,console

+12
source share

I want to add an excellent answer to sma and explain why I need to return a new object from Object.assign .

Using the reduction method, if the reducer returns the same link that it received in the state parameter, redux will assume that the state has not changed and will not update the views. To tell the redux that you are changing state, you must return a new link. Therefore, you will always see a new empty object {} as the first parameter of Object.assign in reducers.

+2
source share

All Articles