如何通过 redux-persist 阻止 redux-form “form”状态自动再水化

Posted

技术标签:

【中文标题】如何通过 redux-persist 阻止 redux-form “form”状态自动再水化【英文标题】:How to stop redux-form's "form" state from auto-rehydrated by redux-persit 【发布时间】:2018-03-09 17:20:33 【问题描述】:

我正在使用 redux-form,它提供了一个内置的 reducer,称为“formReducer”,需要向组合的 reducer 注册,以使用 redux 的 store 管理表单状态。

我也在使用 redux-persist 来持久化 redux 存储。

当我不想让我的表单自动重新填充用户在页面重新加载或页面刷新时输入的数据时出现的问题。在我自己编写的普通 reducer 中,我可以简单地为“REHYDRATE”类型的操作(由 redux-persit 调度)添加一个 switch case,以防止状态切片通过仅返回其初始状态或空状态来自动重新水化。但是 redux-form 的 formReducer 是 redux-form 内置提供的,所以无法更改。那么,有没有办法“定制”redux-form reducer 来添加那个 switch case?或者,有什么方法可以将 redux-persist 配置为不自动重新水化特定的状态切片,或者有什么方法可以将 redux-form 配置为不通过页面重新加载或页面刷新来自动填充?

【问题讨论】:

【参考方案1】:

根据@jpdelatorre 从这个线程How to handle redux-form/CHANGE in reducer 的建议,我有一个“完美”的解决方案

基本上就是“扩展”redux-form提供的formReducer,然后为事件“REHYDRATE”添加switch case:

import  reducer as reduxFormReducer  from 'redux-form'
import  REHYDRATE  from 'redux-persist/constants'

const formPlugin = 
    my_redux_form_name: (state, action) => 
        switch (action.type) 
            case REHYDRATE:
                return 

            default:
                return state
        
    


const formReducer = reduxFormReducer.plugin(formPlugin)
export default formReducer

然后让扩展减速器向根减速器注册。

import formReducer from './form.reducer'
const rootReducer = combineReducers(
    ...other reducers,
    form: formReducer
)

【讨论】:

如果你使用 redux-persist 的白名单配置选项(或黑名单,但最好使用白名单),这是不必要的。它将轻松解决这个头痛。请参阅文档:github.com/rt2zz/redux-persist/blob/master/docs/…【参考方案2】:

如果您使用的是最新 (v5) 的 redux-persist 版本,则在 persistConfig 选项中有一个白名单键选项,您可以在其中将哪些减速器列入白名单应该被持久化/再水化。你应该使用它,例如:

const persistConfig = key: 'root_key_in_localstorage', storage, whitelist: ['session'],

【讨论】:

【参考方案3】:

您可以使用Middleware 来处理这个特定的动作类型并防止它被传递给reducers。

const myMiddleWare = store => next => action => 
  if(action.type != 'REHYDRATE')
     next(action); // pass the action forward to the reducers
   else
    // do your logic here, you can use store.dispatch to dispatch other actions
    // when your not invoking  next(action) this action won't pass through to all the reducers
  

【讨论】:

如何阻止事件传递到特定的 reducer? 什么意思?减速器正在处理所有动作类型? REHYDRATE 是由 formReducer 处理的类型,您希望它不处理它但其他减速器应该处理它吗? 对不起,我的问题似乎令人困惑。我想要的是:我仍然希望所有状态,包括“表单”状态,都由 redux-persit 管理。但我不希望“表单”状态,只有“表单”状态,在页面重新加载或页面刷新时自动补水。一种方法是“挂钩”到 formReducer,为动作“REHYDRATE”添加一个开关盒,然后只返回初始状态或只是一个空对象 。但我不知道该怎么做。 我不明白,谁在调度动作类型REHYDRATE 以及哪些reducer 处理它?以及您希望处理哪些减速器?

以上是关于如何通过 redux-persist 阻止 redux-form “form”状态自动再水化的主要内容,如果未能解决你的问题,请参考以下文章

React native + redux-persist:如何忽略键(黑名单)?

React通过redux-persist持久化数据存储

除了我不想在 redux-persist 中清除的内容之外,如何清除所有内容?

如何解决:console.error:“redux-persist 未能创建同步存储。回退到“noop”存储

如何解决 redux-persist 创建同步存储失败。回退到 React.js 中的 noop 存储

为啥 Redux-Persist 不持久化存储