'How can you replace entire state in Redux Toolkit reducer?

EDIT: The solution is to return state after I replace it completely (return state = {...action.payload})! But why? I don't need to return it when I replace the fields individually.

I'm working with the Redux Toolkit, which simplifies some Redux boilerplate. One thing they do is use Immer to allow you to directly 'modify' state (in fact, you're not). It works fine, except I don't know how to replace my section of state entirely. For instance, I want to do something like this

const reducer = createReducer({ s: '', blip: [] }, {

    [postsBogus.type]: (state, action) => {
        state = { ...action.payload };
    }

but state remains untouched. Instead I have to do this

[postsBogus.type]: (state, action) => {
    state.s = action.payload.s;
    state.blip = action.payload.blip;
}

Is there a way I can replace state entirely?



Solution 1:[1]

Yes, as you noted, you must return a new value to replace the state entirely.

Even in a "plain" Redux reducer, assigning state = newValue does nothing, because all that does is say that the local function variable named state is now pointing to a different value in memory. That does nothing to return a new value.

For Immer specifically, you can either mutate the contents of the Proxy-wrapped state value as long as it's an object or array, or you can return an entirely new value, but not both at once.

Solution 2:[2]

You can, but not in this way, when you say:

function x(y){
   y = 4
}

You're mutating the function parameter, but not the state of redux, you have two options to update this state of your redux store:

either to set state.your_state_name = something or, in your case, what you want to do is to return a new object, the new object is what the new state value is going to be.

simple example:

myReducerFunc: (state, action) => {
  return {...action.payload }
},

another example:

const loggedInUserSlice = createSlice({
  name: '$loggedInUser',
  initialState: {
    isLoggedIn: false,
  },
  reducers: {
    loggedIn: (state, action) => {
      return {
        isLoggedIn: true,
        ...action.payload,
      }
    },
  },
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Normal