Purpose of the Spread syntax in React-Redux Reduce

2019-07-16 16:29发布

问题:

I'm trying to understand the purpose of the spread operator. From what I understand from the documentation, the spread syntax copies over the existing object and gets overridden when a new object is passed in. in the code below:

export default function reducer(state={
    user: [],
    fetching: false,
    fetched: false,
    error: null,
  }, action) {

    switch (action.type) {
      case "FETCH_USER_FULFILLED": {
        return {
          ...state,
          fetching: false,
          fetched: true,
          user: action.payload,
        }
      }
    }

    return state
}

So if my understanding is correct this means that '...state' returns the object:

 {
    user: [],
    fetching: false,
    fetched: false,
    error: null,
  }

So if i substitute '...state' with the object i should get this:

 {
    user: [],
    fetching: false,
    fetched: false,
    error: null,
    fetching: false,
    fetched: false,
    user: user.payload
  }

Wouldn't it be redundant?

回答1:

One of the core concepts of Redux is that you never mutate state. When you start to mutate your state object, predictability and reliability of the App suffers.

This is how Redux expects you to use reducers:

  • Every single time, you must return the new state object.
  • Even if you don't use a library like Immutable, you need to completely avoid mutation.

So it is all about the immutability guarantee. In order to achieve that we can use a library like Immutable or do it ourselves using Object.assign().

Object spread syntax is an elegant and clean alternative for Object.assign().

Consider:

var x = { a: 1, b: 2 };

now,

var y = Object.assign({}, x, { b: 3, c: 4 });

is equivalent to:

var y = { ...x, b: 3, c: 4 };

either way y gets the value { a: 1, b: 3, c: 4 }.


So in our reducer we may write:

return Object.assign({}, state, {
    product: Object.assign({}, state.product, {
        amount: action.calculated_price
    })
});

alternatively the spread way (which gives a better readable code):

return {
    ...state,
    product: {
        ...state.product,
        amount: action.calculated_price
    }
};

Read more here.



回答2:

objects can have only one thing corresponding to one key so there can't be two user properties of an object. the idea of spread operator is that it spreads the object it is applied to. For this example above same code you might not know all the properties of state and you want to change only some specific properties like fetching, fetched, and user.

Using spread operator is same as using Object.assign

Object.assign({}, state, {
      fetching: false,
      fetched: true,
      user: action.payload
})

but spread operator gives you a cleaner syntax to make an object which has some same properties and values with some other object