Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop redux-form's "form" state from auto-rehydrated by redux-persit

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?

like image 809
Hung Nguyen Avatar asked Sep 28 '17 04:09

Hung Nguyen


People also ask

What is rehydrated in Redux persist?

"persist/REHYDRATE":This phase is where the persisted data stored in browser replace the data in Redux store. Across all reducers, every local state is "rehydrated" and is replaced by the persisted store. Each reducer replaces their content by the persisted one.

What is persisted reducer?

According to the docs, persistReducer "returns an enhanced reducer". I guess this means that it wraps your reducer into a function that will persist the new state for you automatically.

Does Redux state persist on refresh?

When we refresh page in a web-app, the state always resets back to the initial values which in not a good thing when you try to build some large web-app like e-commerce. We can manually do the state persistent using the native JavaScript localStorage.


3 Answers

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
})
like image 179
Hung Nguyen Avatar answered Oct 27 '22 11:10

Hung Nguyen


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'], }

like image 33
tommyalvarez Avatar answered Oct 27 '22 11:10

tommyalvarez


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
  }
}
like image 23
Sagiv b.g Avatar answered Oct 27 '22 10:10

Sagiv b.g