I am using Redux for state management.
How do I reset the store to its initial state?
For example, let’s say I have two user accounts (u1
and u2
).
Imagine the following sequence of events:
User
u1
logs into the app and does something, so we cache some data in the store.User
u1
logs out.User
u2
logs into the app without refreshing the browser.
At this point, the cached data will be associated with u1
, and I would like to clean it up.
How can I reset the Redux store to its initial state when the first user logs out?
I have created actions to clear state. So when I dispatch a logout action creator I dispatch actions to clear state as well.
User record action
Logout action creator
Reducer
I am not sure if this is optimal?
I found that the accepted answer worked well for me, but it triggered the ESLint
no-param-reassign
error - https://eslint.org/docs/rules/no-param-reassignHere's how I handled it instead, making sure to create a copy of the state (which is, in my understanding, the Reduxy thing to do...):
But maybe creating a copy of the state to just pass it into another reducer function that creates a copy of that is a little over-complicated? This doesn't read as nicely, but is more to-the-point:
why don't you just use
return module.exports.default()
;)Note: make sure you set action default value to
{}
and you are ok because you don't want to encounter error when you checkaction.type
inside the switch statement.This approach is very right: Destruct any specific state "NAME" to ignore and keep others.
One way to do that would be to write a root reducer in your application.
The root reducer would normally delegate handling the action to the reducer generated by
combineReducers()
. However, whenever it receivesUSER_LOGOUT
action, it returns the initial state all over again.For example, if your root reducer looked like this:
You can rename it to
appReducer
and write a newrootReducer
delegating to it:Now we just need to teach the new
rootReducer
to return the initial state afterUSER_LOGOUT
action. As we know, reducers are supposed to return the initial state when they are called withundefined
as the first argument, no matter the action. Let’s use this fact to conditionally strip the accumulatedstate
as we pass it toappReducer
:Now, whenever
USER_LOGOUT
fires, all reducers will be initialized anew. They can also return something different than they did initially if they want to because they can checkaction.type
as well.To reiterate, the full new code looks like this:
Note that I’m not mutating the state here, I am merely reassigning the reference of a local variable called
state
before passing it to another function. Mutating a state object would be a violation of Redux principles.In case of using redux-persist, you may also need to clean your storage. Redux-persist keeps a copy of your state in a storage engine, and they will be loaded from there on refresh.
First, you need to import the appropriate storage engine and then, to parse the state before setting it to
undefined
and clean each storage state key.I've created a component to give Redux the ability of resetting state, you just need to use this component to enhance your store and dispatch a specific action.type to trigger reset. The thought of implementation is same as what @Dan Abramov said.
Github: https://github.com/wwayne/redux-reset