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

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

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

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

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


当前回答

只需编辑声明约简的文件

import { combineReducers } from 'redux';

import gets from '../';

const rootReducer = (state, action) => {
  let asReset = action.type === 'RESET_STORE';

  const reducers = combineReducers({
    gets,
  });

  const transition = {
    true() {
      return reducers({}, action);
    },
    false() {
      return reducers(state, action);
    },
  };
  return transition[asReset] && transition[asReset]();
};

export default rootReducer;

其他回答

使用Redux Toolkit和/或Typescript:

const appReducer = combineReducers({
  /* your app’s top-level reducers */
});

const rootReducer = (
  state: ReturnType<typeof appReducer>,
  action: AnyAction
) => {
/* if you are using RTK, you can import your action and use it's type property instead of the literal definition of the action  */
  if (action.type === logout.type) {
    return appReducer(undefined, { type: undefined });
  }

  return appReducer(state, action);
};

如果你想重置一个减速机

例如

const initialState = { isLogged:假 } //这将是你的行动 export const resetReducer = () => { 返回{ 类型:“重置” } } 导出默认值(state = initialState, { 类型, 有效载荷 }) => { 开关(类型){ //你的行动会报应到她头上 例“重置”: 返回{ initialState… } } } //从你的前端 调度(resetReducer ())

使用Redux Toolkit的方法:


export const createRootReducer = (history: History) => {
  const rootReducerFn = combineReducers({
    auth: authReducer,
    users: usersReducer,
    ...allOtherReducers,
    router: connectRouter(history),
  });

  return (state: Parameters<typeof rootReducerFn>[0], action: Parameters<typeof rootReducerFn>[1]) =>
    rootReducerFn(action.type === appActions.reset.type ? undefined : state, action);
};

定义一个动作:

const RESET_ACTION = {
  type: "RESET"
}

然后在每个减速器中假设您使用switch或if-else通过每个减速器处理多个动作。我要拿开关的箱子。

const INITIAL_STATE = {
  loggedIn: true
}

const randomReducer = (state=INITIAL_STATE, action) {
  switch(action.type) {
    case 'SOME_ACTION_TYPE':

       //do something with it

    case "RESET":

      return INITIAL_STATE; //Always return the initial state

   default: 
      return state; 
  }
}

这样当你调用RESET动作时,你的reducer就会用默认状态更新存储。

现在,注销,你可以处理如下:

const logoutHandler = () => {
    store.dispatch(RESET_ACTION)
    // Also the custom logic like for the rest of the logout handler
}

每次用户登录时,不需要刷新浏览器。Store将始终处于默认状态。

store.dispatch(RESET_ACTION)只是详细阐述了这个思想。你很可能会有一个用于此目的的动作创建者。更好的方法是使用LOGOUT_ACTION。

一旦分派了这个LOGOUT_ACTION。然后,一个自定义中间件可以用Redux-Saga或Redux-Thunk拦截这个动作。然而,这两种方法都可以分派另一个动作“RESET”。通过这种方式,存储注销和重置将同步发生,您的存储将为另一个用户登录做好准备。

一种方法是在应用程序中编写一个根减速器。

根减速机通常会将处理操作委托给combineReducers()生成的减速机。但是,无论何时它接收到USER_LOGOUT操作,它都会再次返回初始状态。

例如,如果你的根减速器是这样的:

const rootReducer = combineReducers({
  /* your app’s top-level reducers */
})

你可以将它重命名为appReducer,并编写一个新的rootReducer委托给它:

const appReducer = combineReducers({
  /* your app’s top-level reducers */
})

const rootReducer = (state, action) => {
  return appReducer(state, action)
}

现在我们只需要教新的rootReducer返回初始状态以响应USER_LOGOUT操作。如我们所知,无论操作如何,当调用以undefined作为第一个参数时,约简器都应该返回初始状态。让我们用这个事实来有条件地剥离累积状态,当我们把它传递给appReducer:

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

  return appReducer(state, action)
}

现在,每当USER_LOGOUT触发时,所有减约器都将重新初始化。它们还可以返回与初始值不同的值,因为它们可以检查动作。也要打字。

重申一下,完整的新代码是这样的:

const appReducer = combineReducers({
  /* your app’s top-level reducers */
})

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

  return appReducer(state, action)
}

如果使用redux-persist,可能还需要清理存储空间。Redux-persist将您的状态副本保存在存储引擎中,刷新时将从那里加载状态副本。

首先,您需要导入适当的存储引擎,然后在将其设置为undefined并清除每个存储状态键之前解析状态。

const rootReducer = (state, action) => {
    if (action.type === SIGNOUT_REQUEST) {
        // for all keys defined in your persistConfig(s)
        storage.removeItem('persist:root')
        // storage.removeItem('persist:otherKey')

        return appReducer(undefined, action);
    }
    return appReducer(state, action);
};