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
I'd like to point out that the accepted comment by Dan Abramov is correct except we experienced a strange issue when using the react-router-redux package along with this approach. Our fix was to not set state to undefined
but rather still use the current routing reducer. So I would suggest implementing the solution below if you are using this package
const rootReducer = (state, action) => {
if (action.type === 'USER_LOGOUT') {
const { routing } = state
state = { routing }
}
return appReducer(state, action)
}
My take to keep Redux from referencing to the same variable of the initial state:
// write the default state as a function
const defaultOptionsState = () => ({
option1: '',
option2: 42,
});
const initialState = {
options: defaultOptionsState() // invoke it in your initial state
};
export default (state = initialState, action) => {
switch (action.type) {
case RESET_OPTIONS:
return {
...state,
options: defaultOptionsState() // invoke the default function to reset this part of the state
};
default:
return state;
}
};
The following solution works for me.
First on initiation of our application the reducer state is fresh and new with default InitialState.
We have to add an action that calls on APP inital load to persists default state.
While logging out of the application we can simple reAssign the default state and reducer will work just as new.
Main APP Container
componentDidMount() {
this.props.persistReducerState();
}
Main APP Reducer
const appReducer = combineReducers({
user: userStatusReducer,
analysis: analysisReducer,
incentives: incentivesReducer
});
let defaultState = null;
export default (state, action) => {
switch (action.type) {
case appActions.ON_APP_LOAD:
defaultState = defaultState || state;
break;
case userLoginActions.USER_LOGOUT:
state = defaultState;
return state;
default:
break;
}
return appReducer(state, action);
};
On Logout calling action for resetting state
function* logoutUser(action) {
try {
const response = yield call(UserLoginService.logout);
yield put(LoginActions.logoutSuccess());
} catch (error) {
toast.error(error.message, {
position: toast.POSITION.TOP_RIGHT
});
}
}
Hope this solves your problem!
If you want to reset a single reducer
For example
const initialState = {
isLogged: false
}
//this will be your action
export const resetReducer = () => {
return {
type: "RESET"
}
}
export default (state = initialState, {
type,
payload
}) => {
switch (type) {
//your actions will come her
case "RESET":
return {
...initialState
}
}
}
//and from your frontend
dispatch(resetReducer())
Just a simplified answer to the best answer:
const rootReducer = combineReducers({
auth: authReducer,
...formReducers,
routing
});
export default (state, action) =>
rootReducer(action.type === 'USER_LOGOUT' ? undefined : state, action);
Just an extension to @dan-abramov answer, sometimes we may need to retain certain keys from being reset.
const retainKeys = ['appConfig'];
const rootReducer = (state, action) => {
if (action.type === 'LOGOUT_USER_SUCCESS' && state) {
state = !isEmpty(retainKeys) ? pick(state, retainKeys) : undefined;
}
return appReducer(state, action);
};