DEV Community

Cover image for Redux Toolkit + React: A Perfect Combination for Smooth State Management - A Step-by-Step Tutorial
krishna-Tiwari
krishna-Tiwari

Posted on

Redux Toolkit + React: A Perfect Combination for Smooth State Management - A Step-by-Step Tutorial

Introduction

Hey there πŸ‘‹, I think you are trying to set up the Redux toolkit with React. Don't worry! it would be a little bit overwhelming but I'm here to help you through it!!

At first, the Redux toolkit is a library that simplifies the process of using Redux with your React application. It provides many tools and a convenient way to set up Redux with your React application, so you don't have to worry on huge boilerplate and repetitive tasks.

My view on Redux

I will not go on, to explain the concepts of Redux itself. [Check Redux Documentation for further information]. I am here to tell you some important points about Redux:

  • Redux is a global store for states.
  • Redux may not be compulsory for all projects.
  • You can avoid props drilling [Passing props too deep] using Redux toolkit (RTK).

Still confused πŸ˜– on Redux-toolkit? Just think πŸ’­ about the states in React. You remembered? , Redux provides states that can be accessed from anywhere.

Don't burn your head. Just remember that:

Redux is the global store of States.

What you have done with React states? Remember values and setValues like that:

//Initialize states
const [value,setValues]= useState(0); //initial Value


//accessing values
console.log(value);

//updating values 
setValues(1);
Enter fullscreen mode Exit fullscreen mode

Have you remembered 😍 this Concept? Exactly like this, treat get as a selector and set as a dispatch.

I think this illustration helps you. For further information check out this Documentation.

Image description

Implementation

let's skip this theory apart. And as soon you do, Install devtools for redux.
Devtool plugin links for edge and chrome.

Installation

you need to install two packages:

 npm i @reduxjs/toolkit react-redux
Enter fullscreen mode Exit fullscreen mode

Create a Redux store

src/app/store.js
Enter fullscreen mode Exit fullscreen mode
import { configureStore } from '@reduxjs/toolkit';

export default configureStore({
  reducer: {},
});
Enter fullscreen mode Exit fullscreen mode

configureStore

I want to explain configureStore a little bit. If you want full detailed explanation. Check out Documentation.
Steps for Configure Store.

configureStore has seven several attributes.

  • reducers
  • middleware (optional)
  • devtools (optional)
  • preloadedState (optional)
  • enhancers (optional)

I am not going to explain all of this. I have no experience with all of them.
reducers , devtools and preloadedstate are most essential and used frequently.

Redux devtools

Image description

Once you successfully installed redux dev tools on your browser. It looks like mentioned above.
Go and click on Redux tab.

Image description
It looks like this. If we implemented redux with our project.

Image description

Include the Redux store to App.jsx parent

This makes your whole app access the store.

// hidden for simplicity
import { Provider } from 'react-redux';
import store from './app/store';


// hidden for simplicity
  <Provider store={store}>
    <App />
  </Provider>
// hidden for simplicity
Enter fullscreen mode Exit fullscreen mode

Create a redux state slice

The main idea of creating a slice will produce an action used for dispatch and reducer that we will use in configureStore.
features/counter/counterSlice.js

import { createSlice } from '@reduxjs/toolkit'
Enter fullscreen mode Exit fullscreen mode

now let's define initial states for counterSlice and export it with reducers.

import { createSlice } from '@reduxjs/toolkit'

const initialState = {
  value: 0,
}

export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      // Redux Toolkit allows us to write "mutating" logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a "draft state" and produces a brand new
      // immutable state based off those changes
      state.value += 1
    },
    decrement: (state) => {
      state.value -= 1
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload
    },
  },
})
Enter fullscreen mode Exit fullscreen mode

Note:Example from official redux-toolkit.

In above example we have created three reducers. I mean actions increment , decrement and incrementByAmount.

Now export all these actions (reducers) so that we can use them to change state values.

//all the above goes lies the same

export const { increment, decrement, incrementByAmount } = counterSlice.actions

export default counterSlice.reducer

Enter fullscreen mode Exit fullscreen mode

Add slice Reducers to the store.

Next, we need to import the reducer function from the counterSlice and add it to our store.

app/store.js

import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'

export default configureStore({
  reducer: {
    counter: counterReducer,
  },
})
Enter fullscreen mode Exit fullscreen mode

Implementing useSelector and useDispatch in React Components

Now we can read data from store using useSelector and dispatch actions using useDispatch.

Let's create a component called Counter.jsx , then render this component to App.jsx.

components/Counter.js

import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'

export function Counter() {
  const count = useSelector((state) => state.counter.value)
  const dispatch = useDispatch()

  return (
    <div>
      <div>
        <button
          aria-label="Increment value"
          onClick={() => dispatch(increment())}
        >
          Increment
        </button>
        <span>{count}</span>
        <button
          aria-label="Decrement value"
          onClick={() => dispatch(decrement())}
        >
          Decrement
        </button>
      </div>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Now let's import and render at App.jsx.
App.jsx

import './App.css'
import { Counter } from './components/Counter'

export default function App() {
  return (
    <main>
      <Counter />
    </main>
  )
}

Enter fullscreen mode Exit fullscreen mode

Congratulation πŸŽ‰πŸŽ‰ You have completed the complete redux-toolkit setup with react.

AND FINAL PROJECT LOOKS LIKE THIS.....

Image description

Now any time you click the Increment and Decrement buttons:

  • The corresponding redux action will be dispatched to the store.
  • The counter slice reducer will see the actions and update it's state.
  • The <Counter> component will see the new state value from the store and re-render itself with the new data.

Source Code
Feel Free to ask any questions πŸ™‹β€β™‚οΈ and leave your commentπŸ—¨οΈπŸ—¨οΈ.

Top comments (0)