Dan Abramov answers this dilemma in the linked source. In another answer below his is information on clearing all state if you use redux routers in addition to this, but in most instances, Abramov's method is what to do.
Instructions...
In your root reducer, create another reducer called appReducer. This should actually be the exact same thing as your rootReducer.
Now, create a new rootReducer and have it look for the action of 'LOGOUT', and if it is received, it clears sets the overall state to 'undefined' which has the effect of blanking out all properties within the state. It is not mutating anything, it is just changing the values that the properties contain.
Then, after you clear the state, you return appReducer and pass in the state and the action. This way, if it is just a normal action, not LOGOUT, then it the action with the current state will be sent to the appReducer, which will do what it did when it was called the rootReducer.
const appReducer = combineReducer({
reducer1, reducer2, reducer3
})
const rootReducer = (state, action) => {
if(action.type === 'LOGOUT'){
state = undefined
}
return appReducer(state, action)
}
See
Abramov's article for better, clearer doc on how and why this works.