1. 13
    Redux: Reducer Composition with Arrays
    2m 21s

Redux: Reducer Composition with Arrays

Dan Abramov
InstructorDan Abramov

Share this video with your friends

Send Tweet

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

Demetri Ganoff
Demetri Ganoff
~ 5 years ago

It seems like when you separated the logic for "ADD_TODO" and "TOGGLE_TODO", there was some duplication of logic with the switch statements. Wouldn't it be easier to have separate JavaScript functions for each action type? This way they wouldn't be concerned with the action string and only handle the logic of creating the new state.

Dan Abramov
Dan Abramovinstructor
~ 5 years ago

What duplication are you referring to specifically? I don’t see it in the end result. That said, you can definitely make functions even more granular if you’d like to.

Demetri Ganoff
Demetri Ganoff
~ 5 years ago

The switch statement in the todo and todos functions have the same logic. Instead, if you create a addTodo and toggleTodo function that only handles returning the state for those actions, you can eliminate their concern with the action. Of course, this is no longer composing reducers, but separating functionality into easier-to-read chunks.

Dan Abramov
Dan Abramovinstructor
~ 5 years ago

I’m probably missing your point. Aside from having a switch with the same constants, I don’t see any duplication in their logic. The todos reducer handles changes in array, and todo reducer handles changes to individual todo. There is no shared code between them, again, except for the switch statement. As the logic gets more complicated (more actions are handled), todo reducer will grow, but todos will stay pretty much the same. That’s the point of separating them. If they’re not separated, adding more actions that change individual todos will require copy-pasting code for changing todo at an index—now that would be duplication. If you don’t agree please provide some code examples of the duplication you’re referring to (please mark duplicated logic with comments), and how you suggest to reduce that duplication.

Joel Hooks
Joel Hooks
~ 5 years ago

It seems like when you separated the logic for "ADD_TODO" and "TOGGLE_TODO", there was some duplication of logic with the switch statements. Wouldn't it be easier to have separate JavaScript functions for each action type? This way they wouldn't be concerned with the action string and only handle the logic of creating the new state.

When I'm removing duplication, I like to think of it in more functional terms. I don't want to have separate functions for action types, but instead want to provide pure functions that return the new data. I didn't see the logic duplication you are talking about in this case. You can clone JSBins easily and paste a link if you have some ideas for improvement. That'd be great!

At the end of the day, definitely remove duplicate logic with pure functions anytime it makes sense!

Dan Abramov
Dan Abramovinstructor
~ 5 years ago

Here’s a different version, with createReducer abstracted away. This removes the switch statement, and I hope, makes it clear there is no duplication between todos and todo:

https://jsbin.com/yezuramoxi/1/edit?js,console

Demetri Ganoff
Demetri Ganoff
~ 5 years ago

Thanks for the responses! I agree that the only real logic duplication is in the switch statements. Here's an example of what I was envisioning: https://jsbin.com/rosuvobate/1/edit?html,js,console

Please let me know if this is acceptable within the best practices of Redux. Thanks!

Dan Abramov
Dan Abramovinstructor
~ 5 years ago

This is acceptable, but when you add more actions that change a single todo (e.g. EDIT_TODO) you’ll find yourself duplicating the logic to map over the array and change a single item. :-)

There are no strict rules here. Do whatever makes sense. However I think you’re mistaken when you say switch statements are duplication. In a large app, you’ll have a switch statement inside every reducer, and some of them will handle the same actions. This is normal—not something to abstract away. With the approach you’re suggesting, you’re trading a visual duplication (switch statements) for logical duplication (code to update a single item in an array). Anyway, it’s up to you. And this example is small enough that it’s hard to agree on a single best practice—it can be done in a variety of ways all of which are fine.

Demetri Ganoff
Demetri Ganoff
~ 5 years ago

I see what you mean about the map duplication when adding more actions. I definitely what to keep my code scalable and free from logical duplication.

Thanks again and great job on the videos!

Abe Massry
Abe Massry
~ 5 years ago

Transcript says: you return the current trait to avoid all [inaudible 1:36] in the future Should be: you return the current state to avoid odd bugs in the future

Enoh Barbu
Enoh Barbu
~ 4 years ago
Patrick Akpala
Patrick Akpala
~ 3 years ago

i know this is probably 2 years late but why does passing undefined in the todo allow the test to pass ? is this because the creation of the reducer function that was abstracted doesn't know the initial state for the ADD_TODO action?

would it be wrong to pass an empty array into the todo function that gets called in the ADD_TODO?

thanks for your reply

Eleni Lixourioti
Eleni Lixourioti
~ 3 years ago

@Patrick and anyone with the same question of "why do we pass undefined to todo():

The state argument in the context of the todo() function refers to the state of a single todo item. In the case where we're adding a todo item ('ADD_TODO'), there isn't a previously existing todo item to pass a previous state of, as we're only just creating it.

Therefor the reducer takes "nothing" as a state (represented by undefined) and creates "something" as the new state (a new todo object).