Accessing other parts of the state, when using combined reducers

前端 未结 4 651
情歌与酒
情歌与酒 2020-12-29 05:42

NB: This is a question, very similar to Redux; accessing other parts... but it has nothing to do with Router :( thus cannot be solved s

相关标签:
4条回答
  • 2020-12-29 05:56

    You don't have to use combineReducers().

    From the official Redux docs:

    This helper is just a convenience! You can write your own combineReducers that works differently, or even assemble the state object from the child reducers manually and write a root reducing function explicitly, like you would write any other function.

    You may call combineReducers at any level of the reducer hierarchy. It doesn’t have to happen at the top. In fact you may use it again to split the child reducers that get too complicated into independent grandchildren, and so on.

    So your proposed solution is definitely one way you can do it.

    Thanks to @MichelleTilley for spearheading the train of thought!

    0 讨论(0)
  • 2020-12-29 05:57

    I use Thunk to getState(), prepare the data from the full store, then dispatch an action.

    You can put the decision logic in the reducer or in the action. It is up to you. I prefer fat actions and thin reducers but there is no right/wrong.

    Leonardo

    0 讨论(0)
  • 2020-12-29 05:59

    Intro

    I'd like to add an answer, which is based on my 3y+ experience and also recaps some of the other answers and comments above (Thanks to all the contributors)

    Short Answer

    An original combineReducers can be used. Every selector works with Root State. Reducer mutates only it's part of the Root State. Reducer is as thin as possible, and only Action (or Thunk) is responsible for collecting all the data, needed to reduce the part of the Root State

    Detailed Answer

    Application's reducers, actions and selectors are organised using Ducks approach. Using Redux Thunk gives lot of benefits (thanks to Leonardo).

    If we use definitions of my initial question, one single "Duck" - is "one part of the state", and it groups following major items:

    • Reducer (usually a function named %duckName%, receives )
    • Actions and Thunks
    • Selectors (which receive root state)
    • Types (type, interface, enums)

    State of the application - is an object. It's keys - are the names of all the "Ducks" that participate in reducing application's state.

    Reducers shall be kept as thin as possible, as Leonardo has advised.

    All of the Actions and Thunks, can be split into following categories:

    1. Duck Action
      • no selectors inside
      • arguments have all the info, which is sufficient for independent work
      • returns Action object { type: "%actionName%", payload: ... }
    2. Duck Thunk
      • no external selectors, but can have internal ones (selecting from the same Duck)
      • does dispatch of one or more Duck Actions.
      • might dispatch other Duck Thunks, but shall be avoided, as it leads to high complexity of the application.
    3. Smart Duck Thunk
      • is aware of other Ducks existence, thus might select from other Ducks
      • shall not dispatch to other Ducks, as in this case, it might considered as Application Action
    4. Application Action
      • returns Duck Action or other Application Action with modified arguments
    5. Application Thunk
      • have selectors from any of the ducks
      • might dispatch any of the Thunk or Action

    In some cases, you can have more than one Application in your codebase. Your Applications might share some of the Ducks. Sometimes you need to create Duck for every Application, so you can pass some configuration. But these are puzzles of a different story :)

    I've tried to cover minimal portion of them in this repository, which I intend to keep contributing to. It's written using Typescript. I hope it makes it more easier to understand

    0 讨论(0)
  • 2020-12-29 06:09

    You can try to use:

    redux-named-reducers

    Which allows you to get state anywhere in your code like so:

    const localState1 = getState(reducerA.state1)
    const localState2 = getState(reducerB.state2)
    

    Works with combineReducers such that each reducer only handles local state but can access external state if needed.

    0 讨论(0)
提交回复
热议问题