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

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

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

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

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


当前回答

除了Dan Abramov的回答之外,我们是否应该明确地将action设置为action = {type: '@@INIT'}以及state = undefined。采用上述动作方式,各减速器均返回初始状态。

其他回答

我已经创建了清除状态的操作。因此,当我分派登出动作创建者时,我也分派动作来清除状态。

用户记录动作

export const clearUserRecord = () => ({
  type: CLEAR_USER_RECORD
});

注销操作创建器

export const logoutUser = () => {
  return dispatch => {
    dispatch(requestLogout())
    dispatch(receiveLogout())
    localStorage.removeItem('auth_token')
    dispatch({ type: 'CLEAR_USER_RECORD' })
  }
};

减速机

const userRecords = (state = {isFetching: false,
  userRecord: [], message: ''}, action) => {
  switch (action.type) {
    case REQUEST_USER_RECORD:
    return { ...state,
      isFetching: true}
    case RECEIVE_USER_RECORD:
    return { ...state,
      isFetching: false,
      userRecord: action.user_record}
    case USER_RECORD_ERROR:
    return { ...state,
      isFetching: false,
      message: action.message}
    case CLEAR_USER_RECORD:
    return {...state,
      isFetching: false,
      message: '',
      userRecord: []}
    default:
      return state
  }
};

我不确定这是否是最佳的?

下面的解决方案对我很有效。

我添加了重置状态功能到元还原器。关键在于使用

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 {}

你可以通过将此代码添加到动作文件中来清空减速器的数据,

首先导入所有类型:

import * as types from './types';

将此代码添加到注销操作

for(let key of Object.values(types)) {
        dispatch({ type: key, payload: [] });
    }

我已经创建了一个组件来给Redux重置状态的能力,你只需要使用这个组件来增强你的存储和分派一个特定的动作。类型触发重置。执行的想法和Dan Abramov在他们的回答中说的是一样的。

Github: https://github.com/wwayne/redux-reset

只是对@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);
};