Redux: Reducer Composition with Objects

Dan Abramov
InstructorDan Abramov

Share this video with your friends

Send Tweet
Published 6 years ago
Updated 9 months ago

Learn the fundamental pattern of building maintainable Redux applications: reducer composition, and how it can be used to update properties of an object.

[00:00] In the previous lesson, we established the pattern of reducer composition where one reducer can be called by another reducer to update items inside an array.

[00:10] If we create a store with this reducer and log its state, we will find that the initial state of it is an empty array of to dos. If we dispatch an at-to-do action, we will find that the corresponding to do has been added to the state array.

[00:26] If we dispatch another at-to-do action, the corresponding to do will also be added at the end of the array and dispatch in a toggle to do action with ID zero will flag the completed field of the to do with ID zero.

[00:41] Representing the whole state of the application as an array of to dos works for a simple example, but what if we want to store more information? For example, we may want to let the user choose which to dos are currently visible with the visibility filter such as show completed, show all, or show active.

[01:00] The state of the visibility filter is a simple string representing the current filter. It is changed by set visibility filter action.

[01:09] To store this new information, I don't need to change the existing reducers. I will use the reducer composition pattern and create a new reducer that calls the existing reducers to manage parts of its state and combines the results in a single state object.

[01:26] Now that the first time it runs, it will pass undefined as the state of the child reducers because the initial state of the combined reducer is an empty object, so all its fields are undefined. This gets the child reducers to return their initial states and populates the state object for the first time.

[01:45] When an action comes in, it calls the reducers with the pass of the state that they manage and the action and combines the results into the new state object.

[01:56] This is another example of the reducer composition pattern, but this time we use it to combine several reducers into a single reducer that we will now use to create our store. The initial state of the combined reducer now contains the initial states of independent reducers. Any time an action comes in, those reducers handle the action independently.

[02:20] This pattern helps scale Redux's development because different people on the team can work on different reducers handling the same actions without running into each other and causing merge conflicts.

[02:33] Finally, I'm dispatching the set visibility filter action. You can see that it doesn't affect the to dos, but the visibility filter field has been updated.

~ 5 years ago

I don't understand why you are passing undefined to todo?

Michal Frystacky
Michal Frystacky
~ 5 years ago

It lets the specific reducers(todos and visibilityFilter) self populate themselves (with default values) when the todoApp reducer is first called.

~ 5 years ago

This lesson seemed, to take a few extra leaps forward here, the pace previously had been easily understood and constant. The sudden appearance of the store and all the logs, utterly threw me, followed by the rather obfuscated explanation and example of the filters, which seemed almost abstract from the previous lesson. I had to double check I hadn't missed several steps, or even an entire lesson.

I prefer not to continually pause, rewind and play on lessons if its not necessary, but I have to admit, this lesson was a little slow on the uptake.

Zone Chen
Zone Chen
~ 3 years ago

Dear Dan Abramov, If every time some action dispatched with whole state produced again, won't that effect the performance ? If I use redux to make a video player, which listen to timeupdate event and scroll event (all dispatch very frequently), won't that effect performance ? Or there another pattern to use ?

~ 2 years ago

Hi Dan,

Making a function simpler to address one problem per time is not only good for maintenance but also good for tests. The visibilityFilter function in this tutorial is placed at the same level of todos. Can I put visiblityFilter in todos just like todo is called within todos reducer? The point is any guideline to organize these reducers?