redux-ignore icon indicating copy to clipboard operation
redux-ignore copied to clipboard

Unable to merge a part of initial state with predefined state properly

Open ezze opened this issue 7 years ago • 2 comments

I'm trying to implement a deep merging of initial state of application and predefined state received from local storage or server with combineReducers like it's proposed by gaeron.

Consider the following simple example:

import {combineReducers} from 'redux';
const reducer = combineReducers({
    a: combineReducers({
        b: (state = 1, action) => state,
        c: (state = 2, action) => state
    })
});
const store = createStore(reducer, {
    a: {
        b: 3
    }
});
console.log(store.getState()); // => { a: { b: 3, c: 2 } }

As you can see, initial state is merged with predefined one. It also works fine if I use another combineReducers function when a state is an Immutable.Map instance.

Unfortunately, it doesn't work if I apply filterActions:

impoer {combineReducers} from 'redux';
import {filterActions} from 'redux-ignore';
const reducer = combineReducers({
    a: filterActions(combineReducers({
        b: (state = 1, action) => state,
        c: (state = 2, action) => state
    }), 'SOME_ACTION')
});
const store = createStore(reducer, {
    a: {
        b: 3
    }
});
console.log(store.getState()); // => { a: { b: 3 } }

In this case a object from initial state is not merged with a object from predefined state but is fully replaced by it.

ezze avatar Mar 08 '17 00:03 ezze

@ezze this might be related to the issue that the init action is not handled by this plugin: https://github.com/omnidan/redux-ignore/issues/4 - if you can come up with a solution to it, a PR would be very welcome :grin:

omnidan avatar Mar 16 '17 10:03 omnidan

@ezze As it's written, this lib works on individual reducers, but definitely doesn't quite handle a tree of reducers. The internal path forward to handle that I think would be to check if the incoming reducer is a Map/object and recur on handleAction.

The app-code solution I'd look to is to invoke filterActions on the leaves of the internal combineReducers:

const filterSomeAction = reducer => filterActions(reducer, ['SOME_ACTION']);

const reducer = combineReducers({
    a: combineReducers({
        b: filterSomeAction((state = 1, action) => state),
        c: filterSomeAction((state = 2, action) => state),
    })
});
const store = createStore(reducer, {
    a: {
        b: 3
    }
});
console.log(store.getState()); // => { a: { b: 3, c: 2 } }

maxmechanic avatar Oct 12 '17 21:10 maxmechanic