React native + redux-persist: how to ignore keys (blacklist)?

13,108

Solution 1

As per the documentation, the blacklist parameter contains: 'keys (read: reducers) to ignore', so I am afraid it is not possible to implement the behaviour that you want. You can try and implement that functionality yourself, but I think the codebase of the package is really focused on blacklisting reducers instead of properties (see this). I am afraid that the only solution is to create a separate reducer for your non-persistent keys (in my experience it is not much of a hassle).

Solution 2

Use transforms for save separate fields, for example for username in redux-form MyForm inside state.form.MyForm:

const formName = `MyForm`

const formTransform = createTransform(
  (inboundState, key) => {
    return {
      ...inboundState,
      [formName]: {
        values: {
          username: _.get(inboundState, `${ MyForm }.values.username`)
        }
      }
    }
  },
  (outboundState, key) => {
    return outboundState
  },
  { whitelist: [`form`] }
)

persistStore(store, {
  whitelist: [
    `form`
  ],
  transforms: [
    formTransform
  ]
})

Solution 3

You can use Nested Persists for this.

import { persistStore, persistReducer } from 'redux-persist';


const rootPersistConfig = {
  key: 'root',
  storage: storage,
  blacklist: ['auth']
}

// here you can tell redux persist to ignore loginFormData from auth reducer

const authPersistConfig = {
  key: 'auth',
  storage: storage,
  blacklist: ['loginFormData']
}

// this is your global config
const rootReducer = combineReducers({
  auth: persistReducer(authPersistConfig, authReducer),
  other: otherReducer,
})

// note: for this to work, your authReducer must be inside blacklist of 
// rootPersistConfig

const myReducerConfig = {
  key: "cp",
  storage: storage,
  blacklist: ["authReducer"],
  debug: true
};


Solution 4

you have to create reducer for every prop you want to save.

Solution 5

A simple solution is to save the whole reducer in the whitelist and after in the reducer using 'persist/REHYDRATE' action to filter only the keys that you want to keep.

Example:

// configureStore.js
const persistConfig = {
  keyPrefix: 'webapp',
  whitelist: ['filters'],
}

// filtersReducer.js
const projectsBase = {
  [KEYS.SORT]: PROJECTS_SORT_TYPE.NAME,
  [KEYS.TEXT]: '',
}
const itemsBase = {
  [KEYS.SORT]: ITEMS_SORT_TYPE.INDEX,
  [KEYS.TEXT]: '',
}

const base = {
  [KEYS.PROJECTS]: projectsBase,
  [KEYS.ITEMS]: itemsBase
}

export const filters = (state = base, action) => {
  const { type } = action
  switch (type) {
    case PERSIST_REHYDRATE_ACTION_TYPE: {
      if (action.payload.filters) {
        const filters = action.payload.filters
        const projectsSort = _.get(filters, [KEYS.PROJECTS, KEYS.SORT])
        const itemsSort = _.get(filters, [KEYS.ITEMS, KEYS.SORT])
        const newBase = { ...base, 
                         [KEYS.PROJECTS]: {
                             [KEYS.SORT]: projectsSort
                         },
                         [KEYS.ITEMS]: {
                             [KEYS.SORT]: itemsSort
                         }}
        state = newBase
      }
    }
      break
    default:
      break
  }
  return state
}

Share:
13,108

Related videos on Youtube

Mr. B.
Author by

Mr. B.

Updated on July 13, 2022

Comments

  • Mr. B.
    Mr. B. almost 2 years

    I'm storing my settings with redux-persist and would like to ignore some of them to have them reset on every restart, e.g. after a crashing.

    It's possible to add an array of reducer-names as blacklist or whitelist, but I'd like to ignore specific keys, e.g. settings.isLoggedIn instead of settings.

    // ...
    function configureStore(initialState) {
        const store = createStore(
            RootReducer,
            initialState,
            enhancer
        );
    
        persistStore(store, {
            storage: AsyncStorage,
            blacklist: ['router', 'settings'] // works, 'settings.isLoggedIn' doesn't.
        }, () => {
            // restored
        });
    
        return store;
    }
    // ...
    

    Do I have to create another reducer or does anyone a solution to this problem?

    Thanks in advance!