1
votes

Being new to hooks, I was converting some old code that had multiple state properties and I came across this code (lost the link) when searching how to reduce the number of useState hooks I had originally set up. The following useReducer hook code is working as expected. I think I understand that the state value is updated via setState (dispatch), what I am trying to get my head around is how the 2nd argument of the reducer actually copies the values between state and newState using the spread syntax. All the examples I've looked at use a switch statement and various actions that return the new state. Is React doing something in the background to make this copy happen? If anyone can explain how ...newState works as the action of a reducer it would be appreciated:

const reducer = (state, newState) => ({ ...state, ...newState });
const [state, setState] = useReducer(reducer, initialState);
2

2 Answers

0
votes

Normally reducers have switch statement inside but that is not a requirement. Reducer is just a function that takes previous input as first argument, action (type and payload) as second argument and the returns same state (if no condition matches) or a new state. But it is not required to use switch statement. So what are you doing in this reducer is whatever is passed as second argument is being merged in previous state.

const reducer = (state, newState) => ({ ...state, ...newState });

is same as

const reducer = (state, newState) => {
    return { ...state, ...newState };
}

e.g.

const initialState = { a: 1, b: 2 };

On setting new state,

setState({ b: 3, c: 4});

will call reducer with previous state(initial state) and above object as second argument and reducer will return the state after merging

{ ...initialState, ...newState } // pseudo code
{ ...{a: 1, b:2 }, ...{ b:3, c: 4} }
{ a: 1, b: 3, c: 4 } // returned result
0
votes

In your example more like it separate the reducer. It's a little bit confuse when you have only one action.

Try add one more action in your example you will get this:

const reducer = (state, newState) => ({ ...state, ...newState });
const [state, setState] = useReducer(reducer, initialState);
const reducer1 = (state, newState) => ({ ...state, ...newState });
const [state1, setState1] = useReducer1(reducer1, initialState1);

And if you do that in what you mentioned switch way you can do it by that:

const initialState = {someprops, type:1};//you have to sepecify type in state
    const reducer = (state, newState) => {
     switch(state.type){
    case 1:
     return { ...state, ...newState };
    case 2:
    //do something else
     return { ...state, ...newState };
    };
    const [state, setState] = useReducer(reducer, initialState);