Redux-persist: Blacklist nested reducer without external dependencies

Created on 1 Feb 2017  路  11Comments  路  Source: rt2zz/redux-persist

I believe the ability to blacklist (or whitelist if you've gone that route) nested reducers is something that should be available out of the box. In the real world, complex applications have nested stores, sometimes deeply nested.

It would be a mistake to start restructuring a store's architecture based on localstorage persistence, so we need the ability to blacklist nested objects. I'm aware of that redux-persist-transform-filter package, but it depends on Lodash.

Any advice as to how we can do this without any additional dependencies?

Most helpful comment

If the store's architecture is predictable, I would think it'd be trivial to support stuff like:

persistStore(store, { blacklist: ['something.nested_reducer'] })

If you think so, I can look into a PR. Otherwise I'll find another way for my personal use case.

All 11 comments

At now only way I see to use transforms and pass to it store.getStore, because in outbound part of transform u dont have current store state.

May be ask PR extend transform outbound call to (outboundState, key, state) => {}

@lokhmakov Sorry, I don't understand what you mean at all. Blacklisting should happen at the time of calling persistStore in your store creation. There's no need to do things conditionally on store state... state does not matter and the architecture is (presumably) predictable.

@isaachinman U write that ability to blacklist nested reducers need to be available out of the box, without external deps. But it's available without external deps - using transforms.

And in previous message I describe limitation of this method.

If the store's architecture is predictable, I would think it'd be trivial to support stuff like:

persistStore(store, { blacklist: ['something.nested_reducer'] })

If you think so, I can look into a PR. Otherwise I'll find another way for my personal use case.

I want this functionality too.

At now I use something like this:

createTransform(
  (inboundState, key) => {
    return {
      ...inboundState,
      SessionLogin: {
        values: {
          username: _.get(inboundState, `SessionLogin.values.username`)
        }
      },
    }
  },
  (outboundState, key) => {
    return _.merge({ ...store.getState().form }, outboundState)
  },
  { whitelist: [`form`] }
)

Okay, let's see if @rt2zz would accept a PR.

@isaachinman I am very apprehensive about making such a change. While I agree it is a very valid use case, that api reduces net compatability, makes other tools like typing more difficult, and also adds some complexity overhead. Also generally omitting values from an object is slow compared to picking.

I think the solution here is to either write a transform a la https://github.com/rt2zz/redux-persist/issues/266#issuecomment-276628951 or perhaps we can come up with a better lighter weight module that provides sugar around said transform.

Open to further discussion, but I am unlikely to merge anything non-standard into the main module.

@rt2zz Since time is limited in my current build, I've bitten the bullet and simply split my store into two objects, persistable and non_persistable at the top-most level. If someone wrote an easy-to-use transform that doesn't depend on Lodash, I'd probably use it.

I can implement external module for this functionality. But I need:

  1. Access to current state in outbound transformation. This issue I currently resolve taking from store, but redux best practice said dont do it! )
  2. Access to storage in inbound transform, for understand which nested keys present and dont destroy them. And how I understand this is more complicated, because access to storage is async, but outbound transformation is sync

Agree this module needs more support for the reducer.key format, but there's another problem with ['something.nested_reducer']: . is a valid key name: { "foo.bar": "value" }

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

umairfarooq44 picture umairfarooq44  路  3Comments

ucarion picture ucarion  路  4Comments

jamesone picture jamesone  路  4Comments

rturk picture rturk  路  3Comments

admbtlr picture admbtlr  路  3Comments