如何重置Redux存储的状态?

当用户注销时,如何将Redux存储重置为其初始状态?文章提供了多种方法,包括编写根减少器来监听特定操作并返回初始状态,使用redux-persist时清理存储,以及使用组件来实现状态重置功能。
摘要由CSDN通过智能技术生成

本文翻译自:How to reset the state of a Redux store?

I am using Redux for state management. 我正在使用Redux进行状态管理。
How do I reset the store to its initial state? 如何将商店重置为初始状态?

For example, let's say I have two user accounts ( u1 and u2 ). 例如,假设我有两个用户帐户( u1u2 )。
Imagine the following sequence of events: 想象以下事件序列:

  1. User u1 logs into the app and does something, so we cache some data in the store. 用户u1登录到该应用并执行某项操作,因此我们在存储中缓存了一些数据。

  2. User u1 logs out. 用户u1注销。

  3. User u2 logs into the app without refreshing the browser. 用户u2登录到应用程序,而无需刷新浏览器。

At this point, the cached data will be associated with u1 , and I would like to clean it up. 此时,缓存的数据将与u1相关联,我想对其进行清理。

How can I reset the Redux store to its initial state when the first user logs out? 当第一个用户注销时,如何将Redux存储重置为其初始状态?


#1楼

参考:https://stackoom.com/question/2PT3s/如何重置Redux存储的状态


#2楼

One way to do that would be to write a root reducer in your application. 一种方法是在您的应用程序中编写根减少器。

The root reducer would normally delegate handling the action to the reducer generated by combineReducers() . 根减速器通常会将处理操作委派给combineReducers()生成的减速器。 However, whenever it receives USER_LOGOUT action, it returns the initial state all over again. 但是,每当收到USER_LOGOUT操作时,它将再次返回初始状态。

For example, if your root reducer looked like this: 例如,如果您的根减速器如下所示:

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

You can rename it to appReducer and write a new rootReducer delegating to it: 您可以将其重命名为appReducer并编写一个新的授权给它的rootReducer

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

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

Now we just need to teach the new rootReducer to return the initial state after USER_LOGOUT action. 现在,我们只需要教导新的rootReducerUSER_LOGOUT操作之后返回初始状态。 As we know, reducers are supposed to return the initial state when they are called with undefined as the first argument, no matter the action. 众所周知,无论使用什么操作,都必须在以undefined作为第一个参数的情况下调用reducer来返回初始状态。 Let's use this fact to conditionally strip the accumulated state as we pass it to appReducer : 让我们利用这一事实在将累积state传递给appReducerappReducer累积state

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

  return appReducer(state, action)
}

Now, whenever USER_LOGOUT fires, all reducers will be initialized anew. 现在,每当USER_LOGOUT触发时,所有的reducer都会重新初始化。 They can also return something different than they did initially if they want to because they can check action.type as well. 如果愿意,他们还可以返回与最初不同的东西,因为他们也可以检查action.type

To reiterate, the full new code looks like this: 重申一下,完整的新代码如下所示:

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

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

  return appReducer(state, action)
}

Note that I'm not mutating the state here, I am merely reassigning the reference of a local variable called state before passing it to another function. 请注意,我这里没有变异的状态,我只是重新分配参考称为局部变量的state它传递给另一个函数之前。 Mutating a state object would be a violation of Redux principles. 更改状态对象将违反Redux原则。

In case you are using redux-persist , you may also need to clean your storage. 如果您使用redux-persist ,则可能还需要清理存储。 Redux-persist keeps a copy of your state in a storage engine, and the state copy will be loaded from there on refresh. Redux-persist会将状态副本保存在存储引擎中,状态副本将在刷新时从那里加载。

First, you need to import the appropriate storage engine and then, to parse the state before setting it to undefined and clean each storage state key. 首先,您需要导入适当的存储引擎 ,然后在将状态设置为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')

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

#3楼

Simply have your logout link clear session and refresh the page. 只需让您的注销链接清除会话并刷新页面即可。 No additional code needed for your store. 您的商店不需要其他代码。 Any time you want to completely reset the state a page refresh is a simple and easily repeatable way to handle it. 每当您想完全重置状态时,页面刷新都是一种简单且易于重复的处理方式。


#4楼

I've created a component to give Redux the ability of resetting state, you just need to use this component to enhance your store and dispatch a specific action.type to trigger reset. 我已经创建了一个组件来赋予Redux重置状态的能力,您只需要使用此组件来增强您的商店并分派特定的action.type来触发重置。 The thought of implementation is same as what @Dan Abramov said. 实现的思想与@Dan Abramov所说的相同。

Github: https://github.com/wwayne/redux-reset GitHub: https : //github.com/wwayne/redux-reset


#5楼

I'd like to point out that the accepted comment by Dan Abramov is correct except we experienced a strange issue when using the react-router-redux package along with this approach. 我想指出的是,丹·阿布拉莫夫(Dan Abramov)接受的评论是正确的,除了在将react-router-redux软件包与这种方法一起使用时,我们遇到了一个奇怪的问题。 Our fix was to not set state to undefined but rather still use the current routing reducer. 我们的解决方法是不将状态设置为undefined ,而是仍然使用当前的路由简化程序。 So I would suggest implementing the solution below if you are using this package 因此,如果您使用的是此软件包,我建议您实施以下解决方案

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

#6楼

This approach is very right: Destruct any specific state "NAME" to ignore and keep others. 这种方法是正确的:破坏任何特定状态“ NAME”以忽略并保留其他状态。

const rootReducer = (state, action) => {
    if (action.type === 'USER_LOGOUT') {
        state.NAME = undefined
    }
    return appReducer(state, action)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值