Redux-persist: Blacklist nested attributes

Created on 14 Jul 2016  路  8Comments  路  Source: rt2zz/redux-persist

Assuming my store objects looks like this
{ data: {search: {data: [....]}, history:{search: [...], product: [...]}, favourites: {search: [...], product: [...]}}, navigation: {....}, user: {....}}

How can I blacklist data.search, while keeping data.history and data.favourites ?
I've tried with['data.search'], but no luck.

Thank you.

Most helpful comment

As @brunolemos and @rt2zz have suggested the code looks something like this:

import omit from 'lodash/omit'

let blacklistTransform = createTransform(
    (inboundState, key) => {
        if (key === 'data') {
            return omit(inboundState, ['search']);
        } else {
            return inboundState;
        }
    }
)
...
const persistConfig = {
    key: 'root',
    storage,
    transforms: [blacklistTransform],
}

All 8 comments

This is not available out of the box but it should be trivial to write a transform that does that. It would look something like

let blacklistTransform = createTransform(
  (inboundState, key) => {
      if (key !== 'data') return inboundState
      else return {
        ...inboundState,
        data: undefined,
       }
  }
)

while I have not personally used it, this project aims to solve this problem: https://github.com/edy/redux-persist-transform-filter

@rt2zz lodash accept nested paths, so you could use pick for whitelist and omit for blacklist.

There is one more way. Store a getter function in place of nested key which needs to be blacklisted.

let nestedKey = "blacklisted";
let getNestedKey = ()=>nestedKey;
...
{
case REHYDRATE : return {...state,
nestedKey:getNestedKey
};
}

In storage getter function will always be null.

When passing as props call the getter function to get the actual value.

As @brunolemos and @rt2zz have suggested the code looks something like this:

import omit from 'lodash/omit'

let blacklistTransform = createTransform(
    (inboundState, key) => {
        if (key === 'data') {
            return omit(inboundState, ['search']);
        } else {
            return inboundState;
        }
    }
)
...
const persistConfig = {
    key: 'root',
    storage,
    transforms: [blacklistTransform],
}

Here's a slightly more modular version of @gyosifov's solution above:

import omit from 'lodash/omit';

const blacklistPaths = ['prop1', 'prop2', 'prop3.nestedProp'];
const persistConfig = {
    [...]
    blacklist: blacklistPaths.filter(a => !a.includes('.')),
    transforms: [
        // nested blacklist-paths require a custom transform to be applied
        createTransform((inboundState, key) => {
            const blacklistPaths_forKey = blacklistPaths.filter(path => path.startsWith(`${key}.`)).map(path => path.substr(key.length + 1));
            return omit(inboundState, ...blacklistPaths_forKey);
        }, null),
    ],
};

Has anyone come up with a better solution so far?

@Venryx Works well, thank you :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ssorallen picture ssorallen  路  4Comments

openscript picture openscript  路  4Comments

umairfarooq44 picture umairfarooq44  路  3Comments

elado picture elado  路  4Comments

benmvp picture benmvp  路  3Comments