Refactoring Existing Redux w/ Redux Toolkit & Hooks

Brian Lego
Dec 27, 2020 · 6 min read
Image for post
Image for post

During this year’s Reactathon one of the coolest presentation I had to chance to catch was with Mark Erickson. He was there to present some modern Redux techniques and specifically the React Toolkit and the use of the ever popular *hooks*. It inspired me to go back and refactor some of my old Redux code from using the ‘connect’ higher order component to using the Toolkit. So if you’re looking to refactor Redux to make use of it’s hooks I’m gonna walk through a simple refactor and implementation of Redux Toolkit.

First things first I’ll start with a basic React app that has some built in Redux ‘connect’ functionality built into it. For the purposes of this demo it will be a simple store app with an item counter. Below is the basic setup of the three main files that hold Redux functionality. The Reducer, Index.js (where I’m creating my store for the purposes of this demo), and App.js (which is connected to the store’s state and dispatch through it’s props):

Image for post
Image for post
Reducer (left) & Index.js (right)
Image for post
Image for post
App.js

So here we have everything set up. Our App component is subscribed to our Redux store and it’s single piece of state (itemCount) and has it’s single dispatch method to increase the count of itemCount. Its a superrrr simple set up and normally on a larger scaled app you would see an action’s file that held all the different dispatch functions so they could be reused across components but this is fine for a simple demo.

So where do we begin on refactoring our code to make use of Redux Toolkit and then React-Redux hooks? Well, installing it would probably a good idea.

npm install --save @reduxjs/toolkit 

This will install the toolkit which has a few tools conveniently bundled together. This does Not include however React-Redux which you will still need to install if you plan to be using Redux’s hooks (useSelector, useDispatch) but more on that a little later. It also comes with immer, thunk and reselect all of which are useful and will be important to how React Toolkit functions on a larger scale. But we’ll come back to those as well a little later. For now let’s just start with refactoring some of our existing code.

First we’ll go ahead and add a store.js file to our Redux folder. We’re going to move the creation of our store away from index.js and into this file now. Using the Redux Toolkit method configureStore we can import our storeReducer and export to our index.js a fully configured store. If we were to have multiple reducers this would also be where we can combine them (think combineReducers). Below is the refactored code, be sure to note the changes in imports. In store.js we’re now importing from @reduxjs/toolkit.

Image for post
Image for post
New Store.js (left) & Refactored Index.js (right)

Now that we have those two changes done we’ll move on to the real magic, which is going to be in our storeReducer. Here we will utilize my favorite Redux Toolkit method ‘createSlice’. This will essentially combine our Reducer and Actions all together into a ‘slice’ of state. First off, just for sake of clarity I’ll rename the reducer file storeSlice.js and then fix our import from the store.js file. Next, we will start by declaring a new slice using createSlice. We will then configure it with a few things using key/value pairs starting with “name” which will will stick with ‘store’. Next, we will also define its initial state, which for us only includes our itemCount set to zero initially. After the initialState we define our reducers which upon export Redux Toolkit will turn into dispatch actions we can use throughout our application. Ultimately, it should looks something like this and I’ve left the previous Reducer code for reference commented out on the right.

Image for post
Image for post
Refactored reducer into storeSlice

Above you can also see we are exporting ‘increaseCount’ as an action of storeSlice. This is the dispatch method that we will ultimately call within our App component. This now leaves one last export that we’re missing which deals with subscribing to state. Now that we are refactoring away from the ‘connect’ method and not mapping our state/dispatch to props, we will be using the hook ‘useSelector’. We therefore need to export our piece of state (itemCount) right before we export our storeSlice.reducer. Our final storeSlice should ultimately look like this:

State.store.itemCount points to our slice that we named ‘store’ and then within our initialState the itemCount which we set to zero. selectItemCount is of course a conventional naming of the export and you could name it whatever you like. Now finally on to our last refactor which will happen within our App component!

First thing we can do is go ahead and delete all our mapState and mapDispatch code. ‘Un-connect’ our App component and change all our imports so that we now import the two hooks we will need (useSelector & useDispatch) from react-redux. Then we will also import our specific piece of state and our action from our storeSlice (selectItemCount & increaseCount).

The final step is to then utilize them within the component. We declare a variable using ‘useSelector’ which will subscribe our component to that piece of the redux store. We also then declare our dispatch by calling the hook within the component. We then only need to call the dispatch method ‘increaseCount’ onClick of our App button!

Image for post
Image for post
Refactor of App.js

And there you have it! We’ve essentially refactored all our original functionality from Redux’s ‘connect’ methodology to our new Redux Toolkit. This is of course only scratching the surface of what the Redux Toolkit can do. The functionality of being able to manipulate state easily within our newly created slice using Immer allows for direct manipulation of state which is a huge change from how Redux worked previously. In addition Thunk is also included in the Redux Toolkit which allows for asynchronous calls usually to an API. In an upcoming blog post I will expand on this example and add some more complex state manipulation and even some dummy examples of dispatch calls using JavaScripts ‘fetch’.

Of course if you’re looking to take a deeper dive into the functionality of Redux Toolkit and what’s happening ‘under the hood’, the docs provided on their official site are an incredible resource.

[1]: Redux-Toolkit Docs(https://redux-toolkit.js.org/)

[2]: Redux Docs (https://redux.js.org/)

[3]: React-Redux Docs (https://react-redux.js.org/)

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store