我正在使用Redux进行状态管理。 如何将存储重置为初始状态?
例如,假设我有两个用户帐户(u1和u2)。 想象下面的一系列事件:
用户u1登录到应用程序并做了一些事情,所以我们在存储中缓存一些数据。 用户u1退出。 用户u2无需刷新浏览器即可登录应用。
此时,缓存的数据将与u1关联,我想清理它。
当第一个用户注销时,如何将Redux存储重置为初始状态?
我正在使用Redux进行状态管理。 如何将存储重置为初始状态?
例如,假设我有两个用户帐户(u1和u2)。 想象下面的一系列事件:
用户u1登录到应用程序并做了一些事情,所以我们在存储中缓存一些数据。 用户u1退出。 用户u2无需刷新浏览器即可登录应用。
此时,缓存的数据将与u1关联,我想清理它。
当第一个用户注销时,如何将Redux存储重置为初始状态?
当前回答
简单回答一下丹·阿布拉莫夫的问题:
const rootReducer = combineReducers({
auth: authReducer,
...formReducers,
routing
});
export default (state, action) =>
rootReducer(action.type === 'USER_LOGOUT' ? undefined : state, action);
其他回答
只是对@dan-abramov答案的扩展,有时我们可能需要保留某些被重置的键。
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);
};
定义一个动作:
const RESET_ACTION = {
type: "RESET"
}
然后在每个减速器中假设您使用switch或if-else通过每个减速器处理多个动作。我要拿开关的箱子。
const INITIAL_STATE = {
loggedIn: true
}
const randomReducer = (state=INITIAL_STATE, action) {
switch(action.type) {
case 'SOME_ACTION_TYPE':
//do something with it
case "RESET":
return INITIAL_STATE; //Always return the initial state
default:
return state;
}
}
这样当你调用RESET动作时,你的reducer就会用默认状态更新存储。
现在,注销,你可以处理如下:
const logoutHandler = () => {
store.dispatch(RESET_ACTION)
// Also the custom logic like for the rest of the logout handler
}
每次用户登录时,不需要刷新浏览器。Store将始终处于默认状态。
store.dispatch(RESET_ACTION)只是详细阐述了这个思想。你很可能会有一个用于此目的的动作创建者。更好的方法是使用LOGOUT_ACTION。
一旦分派了这个LOGOUT_ACTION。然后,一个自定义中间件可以用Redux-Saga或Redux-Thunk拦截这个动作。然而,这两种方法都可以分派另一个动作“RESET”。通过这种方式,存储注销和重置将同步发生,您的存储将为另一个用户登录做好准备。
除了Dan Abramov的回答之外,我们是否应该明确地将action设置为action = {type: '@@INIT'}以及state = undefined。采用上述动作方式,各减速器均返回初始状态。
你可以通过将此代码添加到动作文件中来清空减速器的数据,
首先导入所有类型:
import * as types from './types';
将此代码添加到注销操作
for(let key of Object.values(types)) {
dispatch({ type: key, payload: [] });
}
为了避免Redux引用初始状态的相同变量,我的建议是:
// 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;
}
};