How to update the whole state?
Regardless of if it's a slice using Redux Toolkit or a basic Redux reducer, if you'd like to replace the whole state, just return a whole new value.
setAuthState(state, { payload }: PayloadAction<IAuthState>) {
return payload; // replaces the whole state
},
Why returning, instead of assigning, updates the state?
state = payload;
state
is a local identifier, reassigning it does nothing outside the function. Though in JavaScript, object references are passed by value, so mutating the state
object inside the function does also mutate the same object anywhere it's referenced outside the function.
Redux Toolkit simplifies state updates by letting devs mutate the passed state
object, which is usually prohibited with immutable states, like in vanilla Redux or with React state.
It uses the Immer library internally, which lets you write code that "mutates" some data, but actually applies the updates immutably. This makes it effectively impossible to accidentally mutate state in a reducer.
Returning a new object in a reducer will just replace the whole state and ignore the proxy object.
Is this what would happen if I did state.profile=payload.profile
, anyway?
Yes, mutating each properties explicitly (taking advantage of RTK's usage of Immer) would do the same, with more code. Though if the payload ever has anymore properties, they wouldn't be included in the slice's state.
This could be what you want, no unwanted data ever gets to the state without explicitly adding it to the reducer. So it's not a bad thing to be explicit.
If you ever have lots of properties though, it could get annoyingly long to maintain.
setAuthState(state, { payload }) {
state.isAuthenticated = payload.isAuthenticated;
state.profile = payload.profile
state.thing = payload.thing
state.stuff = payload.stuff
state.foo = payload.foo
state.bar = payload.bar
// etc...
},
What if I want the whole payload without replacing unrelated state values?
What you could do if the payload
gets longer, but you were in a situation where you don't want to replace the whole state, is to return a new object from spreading the current state and the payload.
setAuthState(state, { payload }) {
return {
...state,
...payload,
};
},