注销时重置Redux状态

Mos*_*ler 3 javascript reactjs react-router redux react-router-redux

我正在尝试在一个较早的线程中解决该问题,该问题通常是如何重置Redux存储状态的?-用户注销时需要重新初始化/使整个Redux存储无效。

但是,就我而言,仍然缺少一些东西。我将Redux与ConnectedRouter结合使用,并且尝试执行以下操作。

将rootReducer定义为:

export default history => 
  combineReducers({
    router: connectRouter(history),
    user,
    manager,
    vendor
    // rest of your reducers
  });
Run Code Online (Sandbox Code Playgroud)

然后,我configureStore将上面的内容导入为createRootReducer

const configureStore = (initialState = {}, history) => {
  let composeEnhancers = compose;
  const composeWithDevToolsExtension =
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
  const enhancers = [];
  const middleware = [sagaMiddleware, thunk, routerMiddleware(history)];
  if (typeof composeWithDevToolsExtension === 'function') {
    composeEnhancers = composeWithDevToolsExtension;
  }
  const store = createStore(
    createRootReducer(history), // root reducer with router state
    initialState,
    composeEnhancers(applyMiddleware(...middleware), ...enhancers)
  );
  store.runSaga = sagaMiddleware.run;
  store.subscribe(() => {
    const state = store.getState();
    const { session } = state['user'];
    if (!session) {
      console.log('no valid session');
      initialState = undefined;
    } else {
      const { token } = session;
      const decodedToken = jwt_decode(token);
      const { exp } = decodedToken;
      const now = new Date();
      if (exp > now.getTime()) {
        console.warn('token expired');
        initialState = undefined;
      } else {
        console.log('token valid');
      }
    }
  });
  return store;
};
export default configureStore({}, history);
Run Code Online (Sandbox Code Playgroud)

想法是initialState = undefined;应该重置我的状态。虽然它对我不起作用。

假设我正在使用ConnectedRouter并将history对象传递给它,那么正确的位置在哪里?

Jos*_*sep 6

在向您提供解决方案之前,我想指出一些非常重要的事情:

  1. 使用redux时,切勿尝试直接更改商店的状态。状态应始终通过减速器更改为对动作的反应。因此,initialState在该subscribe回调中重新分配参数是不正确且毫无意义的。

  2. 我不认为您要“重置” router属性的状态,对吗?

解决此问题的一种方法是使用reducer增强器,如下所示:

const resetEnhancer = rootReducer => (state, action) => {
  if (action.type !== 'RESET') return rootReducer(state, action);

  const newState = rootReducer(undefined, {});
  newState.router = state.router;
  return newState;
};
Run Code Online (Sandbox Code Playgroud)

然后在创建商店时执行以下操作:

  const store = createStore(
    resetEnhancer(createRootReducer(history)),
    initialState,
    composeEnhancers(applyMiddleware(...middleware), ...enhancers)
  );
Run Code Online (Sandbox Code Playgroud)

然后在该subscribe回调中执行以下操作:

if (!session) {
  store.dispatch({type: 'RESET'});
}
Run Code Online (Sandbox Code Playgroud)

最后一个提示:自从您正在使用以来,redux-saga我强烈建议您将subscribe回调中的操作转移到一个传奇中。