Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

In the todoMVC example of the redux project, the reducer for dealing with todos have these 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 portion of the code deals with updating a particular todo item. My question here is that since state.map() will always return a new array. Then, is it still necessary to do:

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

Can it just 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 existing state. I get it. In my example, I have an array of objects. I want to swap the order of the first two elements. Check out the jsbin example here.

  1. Since Array.map always returns a new array, the reference to the returned array is gurranteed to be a new one. Check.
  2. However, the elements within the returned array are not all new. The reference to the first two elements are new. However, the third item is not. It is the same third item as in the old array.

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

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

Does Redux want a new array with new references to each object inside it (even though the values stored within those new objects are identical to the old objects) or just a new array with only the updated elements being new?

like image 474
Cheng Avatar asked Nov 20 '15 13:11

Cheng


1 Answers

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

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

you are creating a brand new object with the enumerable properties of todo and { text: action.text}.

If you do this:

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

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

The first method is making the map operation completely immutable by creating a new array of entirely new objects.

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

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

like image 159
sma Avatar answered Oct 13 '22 01:10

sma