3

Here is my code for persistConfig and store, I want to add blacklist for tracking, but not for all tracking state, but only for tracking.checkingOut, tracking.checkingIn and tracking.searching, how to do this correctly? I understand that if I want to remove tracking completely, I will need to write blacklist: ['tracking'] inside persistConfig, but I'm not sure what to do in case of nested states.

const persistConfig = {
    key: 'root',
    storage: AsyncStorage,
  }

const persistedReducer = persistReducer(persistConfig, reducers)

const createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore);

export const store = createStoreWithMiddleware(persistedReducer);

export const persistor = persistStore(store);

if I will add blacklist like this: blacklist: ['tracking.checkingOut', 'tracking.checkingIn', 'tracking.searching'] will it work? or there should be different approach for this?

Lucky_girl
  • 4,543
  • 6
  • 42
  • 82

3 Answers3

5

You can use persistReducer deeper in your reducer tree:

combineReducers({
  location,
  i18n,
  tracking: persistReducer({ key: 'tracking', storage: AsyncStorage, blacklist: ['whateverYouWantTo'] }),
})

There is an example in the official docs of redux-persist - https://github.com/rt2zz/redux-persist#nested-persists

Kacper Wiszczuk
  • 1,809
  • 11
  • 14
  • How should look like blacklist for a few items then? should it look like blacklist: ['checkingOut', 'checkingIn'] or, blacklist: ['checkingOut'], [ 'checkingIn'] ? – Lucky_girl Oct 21 '19 at 10:36
  • The first option seems okay, check out `redux-persist` docs. Everything is there. – Kacper Wiszczuk Oct 22 '19 at 11:08
4

I recently released an open-source package called Redux Deep Persist, which directly resolves this problem. You can avoid nested redux persist configs, presented in Kacper Wiszczuk's answer. This new approach in creating configs is much simpler and gives you more possibilities.

if I will add blacklist like this: blacklist: ['tracking.checkingOut', 'tracking.checkingIn', 'tracking.searching'] will it work?

Yes, such notation like ['tracking.checkingIn','tracking.checkingOut'] is possible with getPersistConfig method.

Here is what your new config would look like using my "Redux Deep Persist" package:

import { getPersistConfig } from 'redux-deep-persist';

const config = getPersistConfig({
    key: 'root',
    storage: AsyncStorage,
    blacklist: [
        'tracking.checkingIn',  
        'tracking.checkingOut',  
        'tracking.searching.no.matter.how.deep.you.go'
    ],
    rootReducer, // your root reducer must be also passed here
    ... // any other props from the original redux-persist config omitting the stateReconciler
})

You can read more in the official documentation of redux-deep-persist https://github.com/PiotrKujawa/redux-deep-persist/blob/master/README.md

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
3

I do not know if it is possible to apply fully controlled migration for whole state if we will use the answer from @KacperWiszczuk, therefore my variant is:

If you want to make blacklist for any of part of the state you can apply createTransform from 'redux-persist'

Example:

import AsyncStorage from '@react-native-community/async-storage'
import { combineReducers } from 'redux'
import { persistReducer, createTransform } from 'redux-persist'

import localeReducer from './localeReducer' //reducer
import passengerReducers from './passenger' //a set of reducers created via combineReducers

import migrations from './migrations'

const passengerBlacklist = createTransform(
  null,
  (state, key) => {
    {/* Put the code for the initial data here.
        It means when the app will be reopened next 
        data will be cleared/filled up.
    */}
    {/* If you want to not clear but remove the keys, 
        you can use for example omit from 'lodash/omit' here, 
        or any tools what you want
    */}
    const newState = {...state}
    newState.order.from = '' 
    newState.order.to = ''
    return newState
  },
 { whitelist: ['passenger'] }
)

const rootConfig = {
  key: '_store_',
  version: 0,
  storage: AsyncStorage,
  blacklist: [],
  transforms: [passengerBlacklist],
  migrate: migrations,
}

const rootReducer = combineReducers({
  locale: localeReducer,
  passenger: passengerReducers,
})

export default persistReducer(rootConfig, rootReducer)

where passengerReducers is

import { combineReducers } from 'redux'

import orderReducer from './orderReducer'

export default combineReducers({
  order: orderReducer,
})

This is how the whole state looks

enter image description here

Stich
  • 2,331
  • 1
  • 15
  • 31
  • Great one, @Stich! The confusing part for me was the whitelist part. After looking at the docs, it says "define which reducers this transform gets called for." ie slices in the store that are passed through the transform function – Hola Dec 09 '21 at 06:35