How to Progressively Migrate to Redux Toolkit

Redux is a popular application state management solution; an open-source library that can be integrated with front-end frameworks like React and Angular. Redux on its own allows us to achieve global state of the application.

React is another open source UI library that allows you to create interactive user interfaces. React in itself does not provide useful API to manage the global state (Although this problem has been addressed in its latest versions by using context API, most developers still prefer Redux). A combination of React and Redux enables you to write scalable apps with maintainable codebases. However, to add minor features, Redux demands a significant number of lines of codes.

To reduce the boilerplate codes and facilitate easier functionalities the Redux team released Redux toolkit. With Redux toolkit, you need not rewrite existing code. Since it has backward compatibility, the existing code works as expected.

The Redux toolkit (RTK) comes with the Redux Thunk Middleware but we use Redux Saga for asynchronous actions, manage the side effects of the application easily, better code readability, and easy testing.

Steps to Migrate to Redux ToolKit

Here’s a step by step guide to help you to migrate

Step 1

Install the toolkit and remove other packages that come with it, by default.

npm i @reduxjs/toolkit
npm uninstall redux redux-devtools-extension redux-thunk 
Step 2

Replace createStore with configureStore from the toolkit and pass the reducer to the Redux function configureStore , which then returns a store object.

- import { createStore } from "redux";
+ import { configureStore } from "@reduxjs/toolkit";
import rootReducer from "./reducers";

- const store = createStore(rootReducer);
+ const store = configureStore({
+ reducer: rootReducer,
+});

You have now successfully migrated to the Redux toolkit. Moreover, all the codes that already existed will run as usual.

My favourite part of the toolkit is where you can now make use of slices to set up the reducer function for every new feature.

You need not define actions and action creators explicitly. You may simply define the initial state of your store and reducer functions, which are then called when an action is dispatched.

Given below is an example from official docs:

import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
name: 'counter',
initialState: 0,
reducers: {
increment: state => state + 1,
decrement: state => state - 1
}
})

const store = configureStore({
reducer: counterSlice.reducer
})

document.getElementById('increment').addEventListener('click', () => {
store.dispatch(counterSlice.actions.increment())
})

The function createSlice takes an object with three arguments

 {name <string> , initialState <any>, reducer <object>"; 

and returns an object which contains all the action creators in a key named actions with the same function name as the one in reducers. Now, these actions creators return action objects as shown below:

//console.log(counterSlice.actions.increment());
{type: "counter/increment", payload: undefined}
//console.log(counterSlice.actions.increment(4));
{type: "counter/increment", payload: 4}

Keep in mind that the reducer function need not return a new object every time. So, you can mutate it and the Redux toolkit will handle the immutability in the background.

You may sometimes have to access the action type alone and not the object, in which case you can use the toString method. It comes in handy when you use Redux saga to watch for the action types.

counterSlice.actions.increment.toString();
// counter/increment

Following these two steps can help you harness the power of Redux toolkit that works with fewer lines of boilerplate codes, simplified code logic, and better performance. It also makes testing and debugging easier, and comes with features like backwards compatibility and predictable states.

For more details, you can read more about Redux toolkit and its functionalities in the official docs.

1 Like