This video is available to students only

How to Split Reducers and Use combineReducers in Redux

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

Previous LessonHow to Add Undo and Redo to a React Redux AppNext LessonHow to Export an Image From a React Redux App

Lesson Transcript

  • [00:00 - 00:06] Splitting root reducer and using combined reducers. If you look at our state type, you'll see that it has three root level fields.

  • [00:07 - 00:20] Current stroke, the stroke that we are currently drawing, strokes, the list of drawn strokes, and the history index, the number of strokes that were undone. We can organize our code better if we split them into three separate reducers.

  • [00:21 - 01:08] First, let's separate the history index. Create a new folder, as you'll see, modules, inside of it, create another folder called history index, and there create a new file, actions.ts. Copy undo and redo action types from the actions.ts and move it to the history index actions. Copy the undo and redo types, copy the parts of the action union . We'll also use export const and stroke here and stroke and then export the type history index action. There is going to be a union of the undo, redo, and the end stroke type. Type, type of, and stroke, payload, stroke of type stroke and history index of type number.

  • [01:09 - 04:24] Impert the stroke type and export the undo and redo action creators. We copy them from actions.ts, paste here, undo and redo. We also must update the undo type because now it will have the payload. Payload is going to be undo limit that is going to get from the arguments and it's going to be a number. And we must also reflect this in the history index action . The type undo will have payload of type number. Create a new file, reducer.ts. Impert the root state, root state from utils types and import the action types. Impert history index action undo, redo, and and stroke from the actions. Now let's define the reducer itself, export const reducer equals a function that receives a state of type root state history index and the default value is going to be zero. And also an action history index action. Inside of this function, we use a switch statement, switch action type, case and stroke, we return zero case undo, we return math smallest amount between state plus one or action payload. And in case of redo, we do the opposite, we do the biggest amount, math max between state minus one and zero. If we don't recognize the action type default, we just return state without changing it. All right, let's also move the history index selector from the root reducer to the history index reducer. And also we need to remove undo and redo from the action imports. And also from the reducer. Now let's go to the edit panel and update the imports. Now instead of using the root actions, the undo and red o action creators will come from modules, history index actions. And we're also going to need the undo limit, const undo limit equals use selector strokes, length selector, import the use selector, import the stroke length selector from modules strokes reducer. In this reducer , we will have the strokes logic, but also have the strokes length selector there. So as we need it already, let's create another module called strokes. And the final reducer there, redu cer TS. And for now, let's only have the selector. It's going to be a function that receives a state of type root state. Let's import this type and return the strokes length, go back to the edit panel . And now we'll use the undo limit when we send the undo action undo limit, separate the current stroke. Inside of the modules folder, create a new folder, current stroke, and there create a file actions TS.

  • [04:25 - 05:17] First, we need to import the point and the stroke from the utils types. Then we can define the action types, or we can move them from the root actions. Begin stroke, update stroke, set stroke color and end stroke, go to the current stroke module. We'll export the action, we can also move it from the actions, I mean the root actions file. Begin update, set stroke color and end stroke. We'll need to update the end stroke, because now it's going to have a payload. Payload stroke of type stroke and history index of type number. And now we can move the action creators, begin update and end stroke, current stroke actions, and paste them there.

  • [05:18 - 06:04] Go to the color panel and update stroke color import. Now we'll use the action from the modules, current stroke actions. Inside of the current stroke, create the reducer, new file reducer TS. Add the imports, we'll need the action type and the type of the update, begin and end strokes, and the set stroke color actions, and the root state from the utils types. Def ine the initial state, const initial state is root state field current stroke. It's going to be an object that will have points by default is going to be an empty array and the color by default black.

  • [06:05 - 06:21] Now let's define the reducer, export const reducer equals a function with state root state current stroke. The default value is going to be initial state and the action of type action.

  • [06:22 - 06:53] We use the switch statement to process the action type. Now in case of begin stroke, we return a new state with points from action payload. In case of update stroke, we return a new object created from the old state. And we update the points, because previously we just wrote the point from the action payload as the first point in the actual in the points array of our state. Now we're gonna add more points.

  • [06:54 - 07:10] So we take the previous value from the points state points and add the point from the action payload. Then we process set stroke color. Here we take the old state and change the color action payload.

  • [07:11 - 07:22] And we need to make sure that we are returning a new object. And finally we process the end stroke. Case and stroke return new state from the old one and points should be reset.

  • [07:23 - 07:57] If it's some unknown action default, then we just return state. All right, let's also define the current stroke selector here. Expert const current stroke selector equals state root state. And we're gonna return state current stroke. All right, let's remove the action creators from the actions. Actually, we can remove the whole actions dot t as well for now. And inside of the root reducer, we can remove the begin update stroke. You know what, let's remove the whole file.

  • [07:58 - 08:39] We're not gonna need it anyway. The only thing left anyway is to separate the strokes list. In the modules folder, you should already have the strokes folder with the redu cer, where we've defined the stroke length selector. If not, then create this folder. And inside of it, create a new file actions dot t as here will import the stroke from the new deals types. We 'll define the end stroke expert const and stroke equals and stroke. We'll define an action type expert type action type of and stroke payload an object with stroke and history index of type number.

  • [08:40 - 09:59] Define an expert, the action creator and stroke. It's a function that receives a history index of type number and a stroke. Return a new object with type and stroke and payload of type history index and stroke. Now, inside of the reducer, import the action type and the end stroke from the actions and define an expert, the reducer expert const reducer equals a function that receives state root state of the strokes. That default value is an empty array and the action of type action. Inside of this reducer, we'll use switch action type case and stroke. And here we need to get the history index and the stroke from the action payload to be able to check if the current stroke has points. So we get const history index stroke equals action payload and then if the stroke doesn't have points, stroke points length and here we negate it. So if it doesn't have length, then we return state.

  • [10:00 - 10:45] We don't change anything. Otherwise, we return state slice from zero to state length minus history index. And then we put the stroke there. We do it this way so that we override the items that were undone. And if we don't recognize the action, then we return state. All right, just one selector that we didn't move from the root reducer is the strokes selector expert const strokes selector. It's a function that receives a state of type root state and returns state strokes. Update the app component. Go to SRC up TSX update the imports. We don't have the root redu cer anymore.

  • [10:46 - 11:32] And we don't have the root actions. Instead, we'll need to import begin stroke and stroke and update stroke from the modules current stroke actions. We'll need to import the strokes selector from the module stroke reducer modules strokes reducer. And we'll import the current stroke selector from the current stroke reducer and history index selector from the history index reducer accordingly. Now find the end drawing function and update the end stroke call. Here we'll need to pass the history index and current stroke. Make sure to update the end stroke action creator.

  • [11:33 - 12:12] It must receive the history index of type number and the stroke of type stroke. And don't forget to pass in the payload to the action that you're creating history index and stroke . Join the reducers using combine reducers. Go to store.ts. Import combine reducers from Redux. Remove the root reducer import. It doesn't exist anymore. Import the reducers that we've created in the modules folder and rename them accordingly. So the reducer from the history index will be named history index.

  • [12:13 - 12:48] Reducer from the current stroke is current stroke and from the strokes folder is the strokes reducer. Inside of the create store call combine reducers and pass in the object with history index current stroke and strokes reducers. Form the document and let's launch the app. You should still be able to open the application, draw something, use the undo and redo. So it should basically continue to work as it used before. If it does then congratulations, you've successfully migrated to combine reducers.

This lesson preview is part of the Fullstack React with TypeScript Masterclass course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

Unlock This Course

Get unlimited access to Fullstack React with TypeScript Masterclass, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Fullstack React with TypeScript Masterclass