When we deconstruct userReducer we have get access to an array which contains two things, the first item is the state object, the second item is the dispatch function used for mutating the state.

The useReducer function itself takes two arguments. A reducer function (a function with a switch-case to action something dependant of the type action being called), the second argument is the inital state object. Bascially what first instance of you state should look like.

When using useReducer it’s common to also deconstruct the function call in the return array and also then deconstruct the state object within that array like so:

const [{ propA, propB }, dispatch] = useReducer(aReducerFunction, {
  propA: "",
  propB: "",
});

This is probably why userReducer is kind of hard to understand at first glance. This even before we have talked about the reducer function or in this example the aReducerFunction.

The body of aReducerFunction could look something like this:

export const aReducerFunction = (state: any, action: any) => {
  switch (action.type) {
    case "updatePropA":
      return { ...state, propA: action.payload };
    case "updatePropB":
      return { ...state, propB: action.payload };
    default:
      return { ...state, resultMsg: "Not a valid action" };
  }
};

In this example, if a valid action has been provided i.e “updatePropA” or “updatePropB”, we spread the orignal state back into an object and ensure that the property for the relevant propty is updated. spreading the whole original state into a new object and returning it is very much “React” pattern which follows the function programming paradigm of not mutating objects directly. This is our way of updating a reactive object in React.