ioof-holdings / redux-dynostore

These libraries provide tools for building dynamic Redux stores.
BSD 3-Clause "New" or "Revised" License
122 stars 15 forks source link

Static reducers in nested path disappears after attaching dynamic reducer. #424

Closed lubomir-chatoryiskyi closed 3 years ago

lubomir-chatoryiskyi commented 3 years ago

Is it a bug, feature request or question?

Question (or bug)

Which package(s) does this involve?

[@redux-dynostore/core]

Input Code

store.attachReducers({ 'some.path.dynamicReducer1': dynamicReducerFunction });

Current Behavior

Hi! I'm trying to attach dynamic reducer to the store to a nested path. The issue is that in this path I already have static reducers and I'd like to attach a dynamic one. But after attaching static reducers disappears from the state.

some: {
   path: {
       staticReducer1: reducerFuction1,
       staticReducer2: reducerFuction2
   }
}

after calling store.attachReducers({ 'some.path.dynamicReducer1': reducerFuction }); static reducers disappears and I have

some: {
   path: {
       dynamicReducer1: reducerFuction,
   }
}

Expected result:

some: {
   path: {
       staticReducer1: reducerFuction1,
       staticReducer2: reducerFuction2,
       dynamicReducer1: reducerFuction,
   }
}

Your Setup

"redux": "^4.0.5", "react-redux": "^7.1.3", "@redux-dynostore/core": "^3.1.0",

nnnoel commented 3 years ago

I've also encountered this issue. I've also tried specifying the state handler when attaching a reducer, but the custom one doesn't appear to get used.

Configuring the deep state handler in the reducer enhancement worked for me.

import dynostore, { dynamicReducers, deepStateHandler } from "@redux-dynostore/core";

dynostore(dynamicReducers({ stateHandler: deepStateHandler }))
nnnoel commented 3 years ago

@mpeyper The following reproduces this in the integrations spec, though I'm not sure how to fix it. It has something to do with options on this line taking hierarchal precedence. https://github.com/ioof-holdings/redux-dynostore/blob/c2b4da08a772ff3a2a17aa76ec5ac2197154b63a/packages/redux-dynostore-core/src/reducers/createDynamicReducer.js#L15

  test('should attach dynamic reducer to static key with state handler override', () => {
    const reducer = combineReducers({
      group1: combineReducers({
        group2: combineReducers({
          key1: makeTestReducer('key1')
        }),
        key3: makeTestReducer('key3')
      }),
      key5: makeTestReducer('key5')
    })

    const store = createStore(reducer, dynostore(dynamicReducers()))

    store.attachReducers({
      group1: {
        group2: {
          key2: makeTestReducer('key2')
        },
        key4: makeTestReducer('key4')
      }
    }, { stateHandler: deepStateHandler })

    expect(store.getState()).toEqual({
      group1: {
        group2: {
          key1: 'key1 - initialValue',
          key2: 'key2 - initialValue'
        },
        key3: 'key3 - initialValue',
        key4: 'key4 - initialValue'
      },
      key5: 'key5 - initialValue'
    })
  })
mpeyper commented 3 years ago

Thanks for raising @lubomir-chatoryiskyi and investigating a bit @nnnoel.

In general, attaching dynamic reducers to a static reducer node is not allowed with the default state handler (shallow). As @nnnoel discovered, the deep state handler is supposed to allow this, but there are some known issues with using it that have never been resolved and we currently advise against it. Honestly, I think the concept was flawed from the get go and I don't have any ideas for resolving it.

If possible, I'd recommend separating the static reducers from the dynamic reducers at the root of the store, or if that is not possible, creating the store with an empty reducer and attach the static reducers immediately after creation. I'm aware this is not ideal.

burakakca commented 3 years ago

Any improvement? I am also facing the same problem in this regard. I need to add dynamically nested reducers.

mpeyper commented 3 years ago

No changes for this @burakakca. Honestly, I'm not sure how to solve this one in general.

burakakca commented 3 years ago

I'm asking not for this topic but for a quick response. So how can I access a different subspace state from different subspace.

mpeyper commented 3 years ago

@burakakca the general answer is that you don't and if you do need it then perhaps you need to reconsider the boundaries of your subspaces or the use of this library all together. There are some exceptions, namely global state, which is covered in the redux-subspace docs

Please raise a new issue if you want to discuss this further.

mpeyper commented 3 years ago

Closing. Please see #484 for details.