StackOverlord
StackOverlord

Reputation: 85

How the Spread Operator works with Redux Reducer?

I am assigned to a new project which is using React and Redux and they are using much of this spread operator thing in Reducers. I've already searched stackoverflow from similar questions but I still did not get it much.

Sample reducer snippet from our code and retrieves a list of searched records.

//What is the use of adding ...state in the return  
//I tried to remove it but the records returned is still the same 
      return {
        ...state,
        data:  action.orderList,
        isLoading: false,
        error: null
      }

//I also tried to add spread operator on action.orderList but it still returns same data
      return {
        ...state,
        data:  {...action.orderList},
        isLoading: false,
        error: null
      }

//This is where I am confuse some of their reducers is returning ...state.data too and I am not sure why.
//I tried this on my reducer and it did not update my records properly it did not return the searched 
//OrderNumber record only but all records from previous state
      return {
        ...state,
        data:  {...state.data, ...action.orderList}, // **what is the meaning of doing this?**
        isLoading: false,
        error: null
      }





Upvotes: 1

Views: 1393

Answers (2)

Brian Thompson
Brian Thompson

Reputation: 14375

Start with "what is a reducer?".

A reducer takes the previous state and an action, and returns the new state (in its entirety). State must also remain immutable, so you cannot directly change the previous state's properties.

A common convention to accomplish this (like you see here) is to build out your new state object by first "spreading" the properties of the old one. This way you retain all of the old state's values. Then for values you want to actually update, you place them after so that they overwrite the values spread by the old state.

Failure to include the spread operator (or another method of replacing the unchanged state values) means you exclude them from your new state object and they disappear.

Updates to nested properties start this whole process over again. Say you have a nested object:

const state = {a: {b: 'b', c: 'c'}}

To update this object we might first start with this:

const newState = {...state}

This means newState is an exact copy of the original state. To update nested property b, you may be tempted to do something like this:

const newState = {...state, a: {b: 'd'}}

The problem is you did not replace the property c, so it disappears.

Fix this by spreading nested objects too:

const newState = {...state, a: {...state.a, b: 'd'}}

Now you may notice that removing the first ...state makes no functional difference. This is because we manually replaced every property in the object, so it is technically unnecessary. However you may still see people include it either out of habit or to prevent a future edit from causing it to be a problem.

Upvotes: 2

Rohit Khanna
Rohit Khanna

Reputation: 723

The spread operator spreads out the array of object along with which it is used.

What it does is it spreads previous values of state and adds or overrides new values in the final result which is being returned.

For instance: let us assume, the initial value of state is

{
 data:[1,2,3],
 isLoading:true,
 error:"some error",
 someOtherKey="test"
}

now if you run we use your code,

return {
        ...state,
        data:  action.orderList,
        isLoading: false,
        error: null
      }

the output will be

{
   someOtherKey="test",
   data:  action.orderList,
   isLoading: false,
   error: null,
 }

And for this:

 data:  {...state.data, ...action.orderList}, // **what is the meaning of doing this?**

Let us say, action.orderList = {id:1} and state.data={name:"John"}.

Then the final value, which will be assigned to data will be {id:1,name:"John"}.

Upvotes: 1

Related Questions