All reducers will be invoked when an action is dispatched?
Solution 1
Yes, that is correct.
However one option you have to optimize this behaviour (suggested from the Redux docs) is to use 'reselect' https://github.com/rackt/reselect
Reselect basically allows you to create memoized selectors, whereby you can say that props A depends on state B and state C, and therefore only recompute props A if state B or state C changes.
Notice that this will still trigger all of the reducers to run (and go through the switch statement to see if the action might apply to them) - I believe there is no way around this behaviour. Using reselect however means that your top level component will only receive a prop/state change if there was an actual change that affects that state, rather than triggering a change every time and making React re-render everything, even when the change had no effect because it was somewhere unrelated. (The readme in reselect explains better)
Solution 2
Yes - all the reducers will get called when you dispatch the action. You will get one nice side effect to it. Because every reducer returns default state if the action isn't found you get your initial state set up with a single action.
It could be beneficial, although I haven't tried it yet, to have single action affecting multiple reducers aka changing the state in two different part of the store.
When you add reselect to it as @luanped suggested you can get a lot of sick results!
My current stack is:
- Redux for state, actions management
- Reselect for data transformation layer
- React for views
Adding reselect to the work flow and making it work alongside reducers was the best thing that happened to me last week.
Solution 3
You can ignore actions of specific reducer by using https://github.com/omnidan/redux-ignore
import { combineReducers } from 'redux';
// redux-ignore higher-order reducer
import { ignoreActions } from 'redux-ignore'
combineReducers({
counter: ignoreActions(counter, [INCREMENT_COUNTER])
});
Also read about performance on official site https://redux.js.org/faq/performance/#wont-calling-all-my-reducers-for-each-action-be-slow
Related videos on Youtube
Comments
-
hjl almost 2 years
I am using combineReducers to combine all the reducers to create the store, does it mean that any action dispatched from any view will trigger all the reducers being invoked to check the action type?Is it kind of low efficiency?
Or I don't fully understand the redux design principle?
-
hjl over 8 yearsActually I am using vue.js with redux, thanks for your suggestion all the same.
-
luanped over 8 yearsYou are welcome :) but regardless, although all reducers are called, what really happens is that the switch statements are checked, and only the reducer that handles that action will do some work, all others don't do anything, so it really isn't a performance issue. It is worth mentioning that modern JS optimise big switch statements into a jump table with O(1) access time, so you don't need to worry about evaluating large switch statements either in reducers, even if many times the action doesn't match any conditions.
-
hjl over 8 years
a lot of sick results
sounds opposite tobest thing that happened to me
, so are you suggesting to usereselect
? -
Kocur4d over 8 yearsheheh sick as wicked or twisted === good but unexpected.... and yes reselect is a very powerful addition to the work flow. The moment you realize that your selector can return momoized functions that depend on your state you are at home:)
-
Tasnim Reza about 8 years@Kocur4d What do you mean
every reducer returns default state if the action isn't found you get your initial state setup with a single action
? -
Kocur4d about 8 years@Reza all your reducers have
default: return state
in the switch statement. When you dispatch your actiondispatch({type: 'i_am_action', ...})
this action will be seen by all the reducers not only the one that define this action in a case statement. So if you use initial state wisely you will get the starting desired shape of your application with only a single action. -
Tasnim Reza about 8 years@Kocur4d correct me if i'm wrong
default: return state
that doesn't mean it returns always initial state, if you changed your state, then from next time you will get the changed state as default. So it always returns my current sate for any reducer. -
Kocur4d about 8 years@Reza you are correct,
default: return state
always returns the current state. My explanation could be little bit confusing as I was focusing on the initial load of the app. -
Pramod Sharma over 7 yearsAn action observer pattern inside reducer would have better instead of doing it through switch, it is perfect example of observer pattern
-
mnagdev over 2 yearsIt is worth noting that since all reducers are called, if two reducers handle the same action,then both will be invoked