I am trying to deal with the problem, addressed, in general in an earlier thread - How to reset the state of a Redux store? - the need to reinitialize/invalidate the entire redux store on user logout.
In my case, however, something is still missing. I am using Redux with ConnectedRouter and I tried to do the following.
Define the rootReducer as:
export default history =>
combineReducers({
router: connectRouter(history),
user,
manager,
vendor
// rest of your reducers
});
Then I do configureStore
, importing the above as createRootReducer
:
const configureStore = (initialState = {}, history) => {
let composeEnhancers = compose;
const composeWithDevToolsExtension =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
const enhancers = [];
const middleware = [sagaMiddleware, thunk, routerMiddleware(history)];
if (typeof composeWithDevToolsExtension === 'function') {
composeEnhancers = composeWithDevToolsExtension;
}
const store = createStore(
createRootReducer(history), // root reducer with router state
initialState,
composeEnhancers(applyMiddleware(...middleware), ...enhancers)
);
store.runSaga = sagaMiddleware.run;
store.subscribe(() => {
const state = store.getState();
const { session } = state['user'];
if (!session) {
console.log('no valid session');
initialState = undefined;
} else {
const { token } = session;
const decodedToken = jwt_decode(token);
const { exp } = decodedToken;
const now = new Date();
if (exp > now.getTime()) {
console.warn('token expired');
initialState = undefined;
} else {
console.log('token valid');
}
}
});
return store;
};
export default configureStore({}, history);
The idea is that initialState = undefined;
should reset my state. It is not working for me though.
Where would be the correct place to do this, given that I am using the ConnectedRouter
and passing the history
object to it?
I wanted to point out to a couple of things that are pretty important before I give you a solution:
When using redux you should never attempt to alter the state of your store directly. The state should always change through the reducer as a reaction to an action. Therefore, reassigning the parameter initialState
inside that subscribe
callback is incorrect and pointless.
I don't think that you want to "reset" the state of the router
property, correct?
One way to solve this is to use a reducer enhancer, something like this:
const resetEnhancer = rootReducer => (state, action) => {
if (action.type !== 'RESET') return rootReducer(state, action);
const newState = rootReducer(undefined, {});
newState.router = state.router;
return newState;
};
And then when you create your store do this:
const store = createStore(
resetEnhancer(createRootReducer(history)),
initialState,
composeEnhancers(applyMiddleware(...middleware), ...enhancers)
);
And in that subscribe
callback do this:
if (!session) {
store.dispatch({type: 'RESET'});
}
One last extra-tip: since you are using redux-saga
I strongly suggest that you move what you are doing inside that subscribe
callback into a saga.