简体   繁体   中英

React/Redux - Chaining Actions or combining reducers

I am starting to learn React/Redux to build an app. I am trying to determine what best practice is for this situation. I (currently) have three pieces of state in Redux:

  1. A list of filter objects the user specifies
  2. State #1 is passed to an API call that processes it and returns a list of destinations
  3. A third list of buildings that is filtered down by #1 and #2 and is displayed to the user.

So right now when a user changes the filter object, it calls an action that updates #1. However, the list of destinations depends on what the user specifies in #1. My first thought is to let the action flow into a reducer - and then when the #1 object is built, call another action inside the reducer to build #2, which flows through its own reducer.

This instinctively seems...bad. My second thought was to combine #1 and #2 into one object that simply contains both states, process it in a single reducer and store it in Redux as a single piece.

What is considered best practice in this situation?

I think dispatching an action from your reducer breaks unidirectional data flow principle, so best to take that off the table.

Your second approach sounds like good practice but it also depends on how easily state #3 needs to access #1 and #2, and if you're thinking about scalability, it might be best to leave all three as same-level siblings in the state tree.

To achieve this, create one action such as RECEIVE_DATA which might look like this:

{
  type: 'RECEIVE_DATA',
  payload: { /* data from API */ },
  meta: {
    filter: [ /* filter tags */ ]
  }
}

Use an action creator that makes the (async) call to the API. On success, dispatch RECEIVE_DATA and you should have two reducers both listening for RECEIVE_DATA .

One reducer is concerned with state #1 and the other is concerned with #2. They simply subscribe to the part of the state tree they're concerned with and you can return just the action.payload from one and action.meta.filter from the other.

I suggest 'payload' and 'meta' just to be FSA compliant .

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM