Redux Ducks: Restructure your Redux App with Ducks - Robin Wieruch

Redux Ducks: Restructure your Redux App with Ducks - Robin Wieruch

The Redux Ducks: Restructure your Redux App with Ducks tutorial will teach you how to bundle action creators, action types and reducers side by side in your Redux app.

Usually in the beginning of learning Redux you have a technical separation of concerns which gets reflected in the folder structure. Basically there is one folder for your actions and one folder for your reducers. Additionally you collect all action types at one place that they can be reused by reducers and actions.

Since it is often the case that an action is followed by a reducer and both of them share the same action type, a new recommendation came up to collocate all of them at one place. They call it Ducks .

The tutorial itself will not strictly follow all proposed guidelines of the recommendation, but it gives you a good understanding of how your app would look like after the refactoring and the advantages of using the bundling.

Basically we have two ducks in the SoundCloud app: There is one place for the authentication and data fetching and another place where the tracks are saved and played.

Let’s begin with the auth duck: In the existent app you will find the auth actions in src/actions/auth.js and the reducer in src/reducers/auth.js . Moreover there is one action type in the src/constants/actionTypes.js file.

A new folder for the ducks instead of actions / reducers folder pairs will help us to collocate actions and reducers.

At first we can move the sole auth action type.

As you can see we are not exporting anything at this time. We can even more refactor the action type itself to represent the duck bundle. In a growing application it is an improved way to identify the actions and places in the source code.

The next step is to move the action creators. I have highlighted the important pieces after the copy and paste from src/actions/auth.js .

Again we are not exporting anything. Moreover the action creators got prefixed. Since reducers and action creators will live side by side, it is a good way to keep the naming in your file tidy. Additionally we need to import the action creator to set tracks like we did before, but with an alias to follow the new naming convention. We will refactor that later when we have a duck for the track bundle as well.

Last but not least let’s move our reducer.

Note that the reducer is a named function and we prefixed its functions as well. As last step we have to export all the necessary stakeholders.

Usually you don’t need to export the action types, but there may be cases where you have to export. They could be used by tests or other side effect middleware like redux-saga . The example just gives a suggestion how you would accomplish a clean export of all stakeholders.

Now it is time to clean up and remove the files which are unused.

Remove the unused action type ME_SET as well. Keep the remaining action types for now.

src/constants/actionTypes.js

Moreover we can remove the dependency in the entry points of our legacy actions. The file should look like the following without the auth bundle:

src/actions/index.js

After the auth duck is finished and all actions creators and reducers are side by side, we can use the new reducer location to export the combined reducers for the store and use the replaced action creators in the Stream container.

src/reducers/index.js

src/components/Stream/index.js

The app should still be intact after all, but it comes with our first duck!

Now it’s time to create the track duck.

Let’s move the action types, action creators and reducer. Again I highlighted the changed pieces after copy and pasting the relevant lines of code.

Now we provide the store with the relocated reducer like we did with the auth duck.

Same applies for the Stream container component. We can import the actionCreators from their new place.

Remember when we had to import the setTracks as doSetTracks alias in the auth duck? Now we renamed it due to the track duck refactoring and can change that in the auth duck.

As last step we can remove all unused folders and files now.

After the refactoring the folder structure should look like the following:

Finally we have a clean bundling of (action type, action creator and reducer) tuples with the ducks pattern. We still have a reducers folder to combine all of the reducers for the store, but one could move this next to the store to get rid of the reducers folder as well. After that the app would only have components and ducks as main bundling folders.

You may encounter issues in that tutorial. Here you will find some references how to handle issues.

In case you want to know which versions npm installed during that tutorial, here a list of all npm packages in my package.json.

Recommended articles