How to stop redux-form's “form” state from aut

2019-05-07 21:27发布

问题:

I'm using redux-form and it provides a built-in reducer, called "formReducer" that need to be registered with the combined reducers to manage the form state with redux's store.

I'm also using redux-persist to persist the redux store.

The problem raised when I don't want to have my form automatically re-populate the data entered by the user on page reloading or page refreshing. In a normal reducer written by my own, I can simply add an switch case for action of type "REHYDRATE" (dispatched by redux-persit) to prevent the state slice from auto-rehydrating by just returning its initial state or an empty state. But redux-form's formReducer is built-in provided by redux-form, so I cannot change. So, is there any way to "customize" the redux-form reducer to add that switch case? Or, is there any way I can config redux-persist to not auto-rehydrate a specific state slice, or is there any way I can config redux-form to not being auto-populated by page reloading or page refreshing?

回答1:

I have a "perfect" solution based on suggestion by @jpdelatorre from this thread How to handle redux-form/CHANGE in reducer

Basically it's to "extend" the formReducer provided by redux-form, then add switch case for the event "REHYDRATE":

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

then have the extended reducer to register with the root reducer.

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


回答2:

You can use a Middleware that will handle this specific action type and prevent it from being passed to the 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
  }
}


回答3:

If you are using the latest (v5) redux-persist version, in the persistConfig option there's a whitelist key-option where you whitelist which reducers should be persisted/rehydrated. You should use that, e.g:

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