【问题标题】:Resetting redux state on logout注销时重置 redux 状态
【发布时间】:2019-06-09 12:07:42
【问题描述】:

我正在尝试解决这个问题,通常在较早的线程中解决 - How to reset the state of a Redux store? - 需要在用户注销时重新初始化/使整个 redux 存储无效。

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

将 rootReducer 定义为:

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

然后我做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);

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

考虑到我正在使用ConnectedRouter 并将history 对象传递给它,执行此操作的正确位置在哪里?

【问题讨论】:

  • 你有没有试过向reducer发送一个动作来设置状态未定义然后注销?

标签: javascript reactjs redux react-router react-router-redux


【解决方案1】:

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

  1. 在使用 redux 时,您永远不应该尝试直接更改商店的状态。状态应该总是通过 reducer 改变,作为对动作的反应。因此,在 subscribe 回调中重新分配参数 initialState 是不正确且毫无意义的。

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

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

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

  const newState = rootReducer(undefined, {});
  newState.router = state.router;
  return newState;
};

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

  const store = createStore(
    resetEnhancer(createRootReducer(history)),
    initialState,
    composeEnhancers(applyMiddleware(...middleware), ...enhancers)
  );

subscribe 回调中这样做:

if (!session) {
  store.dispatch({type: 'RESET'});
}

最后一个额外提示:由于您使用的是redux-saga,我强烈建议您将您在subscribe 回调中所做的事情转移到一个传奇中。

【讨论】:

  • 虽然您的解决方案不起作用,即使我们在resetEnhancer 周围添加了缺少的),我认为您的想法是正确的。谢谢你。绝对看起来是正确的大方向。但是,状态不会重置。 ;(我会继续玩你给我的东西。感谢帮助。
  • @MosheShmukler 我刚刚更新了我的答案......有两件事是错误的:resetEnhancer 周围的右括号以及在resetEnhancer 内部我正在做action !== 'RESET' 而不是action.type !== 'RESET'。尝试更改这两个,我很确定它会起作用:)
  • 让它工作。你的版本是 99% 正确的,这个想法是完全正确的。``` const resetEnhancer = rootReducer => (state, action) => { if (action.type !== 'LOGOUT_USER') { return rootReducer(state, action ); } const newState = rootReducer(undefined, { type: 'LOGOUT_USER' }); newState.router = state.router;返回新状态; };```
  • createRootReducer(history) 是什么以及它来自哪里?
  • @TheCoder 在 OPs 问题中有解释。这是问题中出现的第一个代码片段。另外,在那之后,OP 说:“然后我做 configureStore,将上面的内容作为 createRootReducer 导入”
【解决方案2】:

您可以执行清除商店的操作并在您的rootReducer 中使用它,如下所示:


const appReducer = combineReducers({
    ... // your reducers
});

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

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export const configureStore = (initialState, history) =>
    createStore(
        connectRouter(history)(rootReducer),
        initialState,
        composeEnhancers(applyMiddleware(routerMiddleware(history), thunkMiddleware))
    );

您将拥有appReducer 和所有reducer,还有rootReducer,它将确定返回相应值或未定义值的函数。

提示:您可以使用注销操作,而不是使用新操作来清除商店

【讨论】:

  • 不幸的是,您的建议还将重新初始化 router 属性,我认为 OP 正在寻找 router 属性未更新的解决方案。除此之外,您的解决方案与我的非常相似:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-27
  • 1970-01-01
  • 2020-12-14
  • 1970-01-01
  • 2021-09-08
  • 1970-01-01
  • 2018-09-07
相关资源
最近更新 更多