1

Just a simple question for the pros. I am building a reducer and a piece of the code looks like this:

export const cusDataReducer = (state = cusDataInitialState, action) => {    
    let newState = {...state}
    switch (action.type) {
        case "CUS_READ":
            newState.data = action.value;
            newState.loading = false;                        
            break;
...

The question I have is what is the difference between state and {...state} in this case? If I change newState=state the code breaks. Console logs of state and {...state}, however, look exactly the same.

This is my store:

import {cusDataReducer} from './cusdata'

let rootReducer = combineReducers({
    cusdata: cusDataReducer
});
export const Store = createStore(rootReducer,applyMiddleware(thunk))
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Elcid_91
  • 1,571
  • 4
  • 24
  • 50
  • [Why can't I directly modify a component's state, really?](https://stackoverflow.com/q/37755997/1218980) – Emile Bergeron Mar 16 '20 at 18:48
  • Just FYI: [Object spread vs. `Object.assign`](https://stackoverflow.com/q/32925460/1218980) – Emile Bergeron Mar 16 '20 at 18:48
  • While the following is for a React state, the same (immutability) principle applies to Redux reducers: [How to update nested state properties in React](https://stackoverflow.com/q/43040721/1218980) – Emile Bergeron Mar 16 '20 at 18:50

1 Answers1

3

This doesn't create a new object:

let newState = state;

The variable newState simply points to the same object as state. Modifying that object is mutating the current state, which is bad.

This, however, does create a new object:

let newState = {...state};

The spread operator (...) is basically a very convenient shorthand for populating that new object with each property of the existing object. A longer version might be something like:

let newState = {
    prop1: state.prop1,
    prop2: state.prop2,
    //etc.
};

By creating a new object, it's no longer the current actual state. You can mutate your new object all you like. Upon returning it, Redux will replace the entire current state with the entire new state.

David
  • 208,112
  • 36
  • 198
  • 279
  • Makes quite a bit of sense. Thanks! – Elcid_91 Mar 16 '20 at 18:44
  • So how is it known which reducer key to update in the store if I add say another reducer called "emldata"? – Elcid_91 Mar 16 '20 at 18:53
  • @Elcid_91: I'm not sure what you mean. The main structure of the reducer is that `switch` which determines which action type is being invoked. Those should all be mutually exclusive. Once you get into the correct `case` then the code is specifically written to perform the necessary updates to state. Whatever fields you need to update for that action, you'd update them. – David Mar 16 '20 at 18:56
  • 1
    OK, I will give it another go, I ask because I had two reducers in the store that were structurally identical. Loaded one key on the store but the other key loaded with the same data....very odd. I will clean muy code up and post in another question if it happens again..Thanks! – Elcid_91 Mar 16 '20 at 18:59