Сброс избыточного состояния при выходе - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь решить проблему, решаемую, как правило, в более ранней ветке - Как сбросить состояние хранилища 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?

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Вы можете выполнить действие по очистке магазина и использовать его в своем 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 со всеми вашими редукторами, но также и rootReducer, которая будет функцией, которая определит возвращение соответствующего или неопределенного значения.

СОВЕТ: Вы можете использовать свое действие Выход из системы вместо использования нового действия только для очистки магазина

0 голосов
/ 15 января 2019

Прежде чем дать вам решение, я хотел бы отметить пару очень важных вещей:

  1. При использовании приставок вы никогда не должны пытаться изменить состояние вашего магазина напрямую. Состояние должно всегда меняться через редуктор как реакция на действие. Поэтому переназначение параметра initialState внутри этого обратного вызова subscribe является неправильным и бессмысленным.

  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 обратного вызова, в сагу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...