我正在使用Redux进行状态管理。 如何将存储重置为初始状态?
例如,假设我有两个用户帐户(u1和u2)。 想象下面的一系列事件:
用户u1登录到应用程序并做了一些事情,所以我们在存储中缓存一些数据。 用户u1退出。 用户u2无需刷新浏览器即可登录应用。
此时,缓存的数据将与u1关联,我想清理它。
当第一个用户注销时,如何将Redux存储重置为初始状态?
我正在使用Redux进行状态管理。 如何将存储重置为初始状态?
例如,假设我有两个用户帐户(u1和u2)。 想象下面的一系列事件:
用户u1登录到应用程序并做了一些事情,所以我们在存储中缓存一些数据。 用户u1退出。 用户u2无需刷新浏览器即可登录应用。
此时,缓存的数据将与u1关联,我想清理它。
当第一个用户注销时,如何将Redux存储重置为初始状态?
当前回答
使用Redux Toolkit的方法:
export const createRootReducer = (history: History) => {
const rootReducerFn = combineReducers({
auth: authReducer,
users: usersReducer,
...allOtherReducers,
router: connectRouter(history),
});
return (state: Parameters<typeof rootReducerFn>[0], action: Parameters<typeof rootReducerFn>[1]) =>
rootReducerFn(action.type === appActions.reset.type ? undefined : state, action);
};
其他回答
对我来说,最好的工作是设置initialState而不是state:
const reducer = createReducer(initialState,
on(proofActions.cleanAdditionalInsuredState, (state, action) => ({
...initialState
})),
下面的解决方案对我很有效。
我添加了重置状态功能到元还原器。关键在于使用
return reducer(undefined, action);
将所有减速器设置为初始状态。返回undefined反而会导致错误,因为存储的结构已经被破坏。
/还原剂index.ts
export function resetState(reducer: ActionReducer<State>): ActionReducer<State> {
return function (state: State, action: Action): State {
switch (action.type) {
case AuthActionTypes.Logout: {
return reducer(undefined, action);
}
default: {
return reducer(state, action);
}
}
};
}
export const metaReducers: MetaReducer<State>[] = [ resetState ];
app.module.ts
import { StoreModule } from '@ngrx/store';
import { metaReducers, reducers } from './reducers';
@NgModule({
imports: [
StoreModule.forRoot(reducers, { metaReducers })
]
})
export class AppModule {}
使用Redux,如果应用了以下解决方案,它假设我已经在所有的reducers(例如{user: {name, email}})中设置了initialState。在许多组件中,我检查这些嵌套的属性,所以有了这个修复,我防止我的渲染方法在耦合属性条件上被破坏(例如if state.user。如果上面提到的解决方案,电子邮件将抛出一个错误用户是未定义的)。
const appReducer = combineReducers({
tabs,
user
})
const initialState = appReducer({}, {})
const rootReducer = (state, action) => {
if (action.type === 'LOG_OUT') {
state = initialState
}
return appReducer(state, action)
}
对我来说,一个快速而简单的选择是使用还原复位。这是简单的,也有一些高级选项,为较大的应用程序。
在创建存储区中设置
import reduxReset from 'redux-reset'
// ...
const enHanceCreateStore = compose(
applyMiddleware(...),
reduxReset() // Will use 'RESET' as default action.type to trigger reset
)(createStore)
const store = enHanceCreateStore(reducers)
在注销函数中调度您的“重置”
store.dispatch({
type: 'RESET'
})
NGRX4更新
如果您正在迁移到NGRX 4,您可能已经从迁移指南中注意到用于组合reducer的rootreducer方法已经被ActionReducerMap方法所取代。起初,这种新的做事方式可能会使重置状态成为一个挑战。它实际上很简单,但这样做的方式已经改变了。
这个解决方案的灵感来自NGRX4 Github文档的元还原器API部分。
首先,让我们假设你正在使用NGRX的新ActionReducerMap选项像这样组合你的reducer:
//index.reducer.ts
export const reducers: ActionReducerMap<State> = {
auth: fromAuth.reducer,
layout: fromLayout.reducer,
users: fromUsers.reducer,
networks: fromNetworks.reducer,
routingDisplay: fromRoutingDisplay.reducer,
routing: fromRouting.reducer,
routes: fromRoutes.reducer,
routesFilter: fromRoutesFilter.reducer,
params: fromParams.reducer
}
现在,假设你想从app。module内部重置状态
//app.module.ts
import { IndexReducer } from './index.reducer';
import { StoreModule, ActionReducer, MetaReducer } from '@ngrx/store';
...
export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
return function(state, action) {
switch (action.type) {
case fromAuth.LOGOUT:
console.log("logout action");
state = undefined;
}
return reducer(state, action);
}
}
export const metaReducers: MetaReducer<any>[] = [debug];
@NgModule({
imports: [
...
StoreModule.forRoot(reducers, { metaReducers}),
...
]
})
export class AppModule { }
这基本上是用NGRX 4达到同样效果的一种方法。