我正在使用Redux进行状态管理。 如何将存储重置为初始状态?

例如,假设我有两个用户帐户(u1和u2)。 想象下面的一系列事件:

用户u1登录到应用程序并做了一些事情,所以我们在存储中缓存一些数据。 用户u1退出。 用户u2无需刷新浏览器即可登录应用。

此时,缓存的数据将与u1关联,我想清理它。

当第一个用户注销时,如何将Redux存储重置为初始状态?


当前回答

首先,在应用程序启动时,减速机的状态是新鲜的,并带有默认的InitialState。

我们必须添加一个动作,调用APP初始加载持续默认状态。

当注销应用程序时,我们可以简单地重新分配默认状态,reducer将像新的一样工作。

APP主容器

  componentDidMount() {   
    this.props.persistReducerState();
  }

主APP减速器

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);
};

注销时调用重置状态的动作

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
    });
  }
}

其他回答

这种方法非常正确:销毁任何特定状态“NAME”以忽略并保留其他状态。

const rootReducer = (state, action) => {
    if (action.type === 'USER_LOGOUT') {
        state.NAME = undefined
    }
    return appReducer(state, action)
}

使用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)
}

对我来说,最好的工作是设置initialState而不是state:

  const reducer = createReducer(initialState,
  on(proofActions.cleanAdditionalInsuredState, (state, action) => ({
    ...initialState
  })),

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达到同样效果的一种方法。

 const reducer = (state = initialState, { type, payload }) => {

   switch (type) {
      case RESET_STORE: {
        state = initialState
      }
        break
   }

   return state
 }

你也可以触发一个动作,由所有或部分还原器处理,你想重置到初始存储。一个动作可以触发你整个状态的重置,或者只是适合你的一部分。我相信这是最简单、最可控的方法。