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

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

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

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

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


当前回答

结合Dan Abramov的回答,Ryan Irilli的回答和Rob Moorman的回答,来解释保持路由器状态和初始化状态树中的其他所有东西,我最终得到了这样的答案:

const rootReducer = (state, action) => appReducer(action.type === LOGOUT ? {
    ...appReducer({}, {}),
    router: state && state.router || {}
  } : state, action);

其他回答

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

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

结合Dan Abramov的回答,Ryan Irilli的回答和Rob Moorman的回答,来解释保持路由器状态和初始化状态树中的其他所有东西,我最终得到了这样的答案:

const rootReducer = (state, action) => appReducer(action.type === LOGOUT ? {
    ...appReducer({}, {}),
    router: state && state.router || {}
  } : state, action);

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

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

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

Dan Abramov的答案是正确的,除了我们在使用react-router-redux包时遇到了一个奇怪的问题。

我们的解决方案是不将状态设置为undefined,而是仍然使用当前的路由减速器。因此,如果您正在使用这个包,我建议实现下面的解决方案

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

我发现Dan Abramov的回答很适合我,但它触发了ESLint no-param-reassign错误- https://eslint.org/docs/rules/no-param-reassign

下面是我如何处理它,确保创建一个状态的副本(这是,在我的理解,Reduxy的事情要做…):

import { combineReducers } from "redux"
import { routerReducer } from "react-router-redux"
import ws from "reducers/ws"
import session from "reducers/session"
import app from "reducers/app"

const appReducer = combineReducers({
    "routing": routerReducer,
    ws,
    session,
    app
})

export default (state, action) => {
    const stateCopy = action.type === "LOGOUT" ? undefined : { ...state }
    return appReducer(stateCopy, action)
}

但是也许创建一个状态的副本,然后把它传递给另一个减速器函数,它会创建一个状态的副本,这有点过于复杂了?这篇文章读起来不太好,但更切题:

export default (state, action) => {
    return appReducer(action.type === "LOGOUT" ? undefined : state, action)
}