Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux and within a reducer accessing a different reducer, how?

So, I have an app that has multiple reducers, and thus multiple action creators associated.

There is a time in which one of my reducers updates the state (because of an edit), and as such, I have to then make sure the other reducers see this update and adjust their state accordingly.

think of it as if a user selects "sneakers", and this state management is in a reducer called productsReducer. As such, as a user moves thru the app process, they get couponsReducer associated with it... but the user can "edit" at any time, so if they then edit "sneakers" and say, choose another producer, I have to be able to alter the couponsReducer in real time, because a progress modal needs to reflect this. I can do this via going thru the flow to the coupon page, because on that page I just reconcile the data on componentWillMount... but the rub is I have a progress modal, and prior to getting to the coupons page, a user can open the progress modal... and there will be a missmatch here...

long winded I know, I just wanted to explain my situation.

so, I want to be able to call "other reducers" or their action creators from within the productsReducer.

Would a middleware be appropriate here, in which I sniff for a certain "action.type" and if I see it, I can dispatch other action.type's or is there a way to call action creators from within the productsReducer?

importing: import * as coupons from './couponsActions' and any other actions I need seem inappropriate.

like image 283
james emanon Avatar asked Mar 07 '16 19:03

james emanon


People also ask

How do you use multiple reducers in Redux?

Having multiple reducers become an issue later when we create the store for our redux. To manage the multiple reducers we have function called combineReducers in the redux. This basically helps to combine multiple reducers into a single unit and use them.

Can multiple reducers handle same action?

Multiple slice reducers can respond to the same action, independently update their own slice as needed, and the updated slices are combined into the new state object. Because this pattern is so common, Redux provides the combineReducers utility to implement that behavior.

How actions and reducers are connected in Redux?

Reducers, as the name suggests, take in two things: previous state and an action. Then they reduce it (read it return) to one entity: the new updated instance of state. So reducers are basically pure JS functions which take in the previous state and an action and return the newly updated state.


2 Answers

Updating state based on the state of application is an anti-pattern. The solution is even simpler:

If an action affects multiple reducers, subscribe to that action in the reducers that care.

So when a user selects sneakers, fire these actions

{ type: 'item_select', payload: 'sneakers' }

and then in couponsReducer, have something like this:

function (state = initialState, action) {
  if (action.type == 'item_select') {
    return { ...state, activeProduct: action.payload);}
  }
  return state;
}

You do not want cascading updates, where states depend on other states changing. You want a simple dispatch architecture where one action affects everything all at once.

like image 133
Nathan Hagen Avatar answered Sep 22 '22 12:09

Nathan Hagen


In many cases it is enough to handle the same action in multiple reducers (which is an officially recommended way of doing things in redux). So always try that solution first.

In more complex cases there are some libraries you can use. For example using redux-saga you could handle it like this:

function* watchItemSelect() {
    while(true) {
        // Wait for the action you are interested in
        const action = yield take('ITEM_SELECT');
        // Send another action
        yield put({type: 'OTHER_ACTION'}) 
        // The loop will now continue and wait until the next ITEM_SELECT action comes
    }
}

There are also other libraries that does the same thing but a little different. Most of them inspired by the elm language:

  • redux-loop
  • redux-side-effect
  • redux-side-effects
  • redux-effects

Also this repo has some info about the thinking in the above libraries:

redux-architecture

like image 23
Jonas Kello Avatar answered Sep 23 '22 12:09

Jonas Kello