How to implement state in React using Redux Toolkit (easy way🔥)
Tags: react, redux, reduxtoolkit, javascript
Published: 2022-06-09 03:34:37

## Introduction 
This tutorial will introduce you to Redux toolkit and teach you how to use it right way following best practices. By the time you finish this tutorial, you should be able to build your own Redux Applications. 

## What is Redux ?
[Redux](https://redux.js.org/) is a library for managing and updating application state using events called `actions`. It serves as a centralized store for state, that needs to be used across your entire application(instead of props drilling), with rules ensuring that the state can only be updated in a predictable fashion.

## What is Redux Toolkit ?
[Redux Toolkit](https://redux-toolkit.js.org/) is an all in one state management library for React.js. It helps you to create and manage global state easily with a lot less boiler plate code. Redux toolkit is basically an extension on Redux and other dependent packages, functions for state management. It simplifies most Redux tasks, prevents common mistakes, and makes it easier to write Redux applications.

## How State management works in Redux ?

![Redux flow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9bahw6i1cct8lvv3t2pp.png)

Assume that you have created an action(*action is a function that triggers the respective reducer*) named `incrementValue` and reducer(*reducer is a function or piece of code, that actually updates the global state known as store based on action event*).

Let's say you have a component with button for incrementing the counter value based on `onclick` event. When you trigger the `onclick` event it will `dispath` an action named `incrementValue`. That action resolves against the respective reducer and updates the global state in store. The registered subscribers of the store will get notified with latest state details. Please find the reference image attached above.

### Steps to implement `Redux Toolkit to your app`

1. Create a new react app and install all the required dependencies
2. Clean the boilerplate code
3. Create a counter app using `useState` (Optional)
4. Implement a store, slice and actions
5. Subscribe and Dispatch events
6. Final thoughts

> Let's see this in action by building a simple `counter application` using redux toolkit.

### 1. Create a new react app and install all the required dependencies
Before creating a react app make sure you installed [Node.js](https://nodejs.org/en/). Once you installed the dependencies use below snippet to create a new react app.
```
npx create-react-app counter-app
cd counter-app
``` 
Use the below command to install dependent packages.
```
npm install @reduxjs/toolkit react-redux react-bootstrap bootstrap
``` 
Add below snippet to public/index.html file. This is for bootstrap cdn.
```
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
``` 
Now run the app using `npm start` command. Open this [url](http://localhost:3000/) If you see something like this.
![initial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8v1pcggwwievyryec2t7.PNG)
Then you have successfully created your react app. 
### 2. Clean the boilerplate code 
Remove everything from App.js and add below snippet.
```
import './App.css';

function App() {
  return (
    <div className="App container-md pt-5">
      <span> Will add details here... 🔥  </span>
    </div>
  );
}
export default App;
``` 
This is how it looks 

![cleanup template](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/151z618510kd5gi7m3bb.PNG)

### 3. Create a counter app using `useState` (Optional)
Create a state variable `counter` for storing the current value. As well as create functions to increment and decrement counter value.
```
import './App.css';
import React, {useState} from 'react';
import { Button } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';

function App() {
  // create a state variable called counter and set it to 0
  const [counter , setCounter] = useState(0);

  // create a function called increment that adds 1 to the counter
  const incrementCounter = () => {
    setCounter(counter + 1);
  }

  // create a function called decrement that subtracts 1 from the counter
  const decrementCounter = () => {
    setCounter(counter - 1);
  }

  return (
    <div className="App container-md pt-5">
      <div className = "pb-3">
      <h2> Simple Counter Application... 🔥 </h2>
      </div>
      <div className = "row">
        <div className = "col-md-5">
          <Button variant="primary" onClick = {incrementCounter}>
            Increment
          </Button>
        </div>
        <div className = "col-md-2">
          <h4>
            {counter}
          </h4>
        </div>
        <div className = "col-md-5">
          <Button variant="primary" onClick = {decrementCounter}>
            Decrement
          </Button>
        </div>
      </div>
    </div>
  );
}

export default App;
``` 
Run the command `npm start` and you will see this below UI.
![use state](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g2t0db1th99w604nnqrx.PNG)
Great 🔥, you are ready to dive deep into the actual topic.
### 4. Implement a store, slice and actions
- Create a store(`src/redux/store.jsx`) which is responsible for subscribing and maintaining the global state.
```
import { configureStore } from "@reduxjs/toolkit";
export const store = configureStore({
    reducer : {}
})
``` 
- Wrap the main component with Provider in index.js as shown below. This will provide access to global state `store` across your application.
```
import { Provider } from "react-redux";
import { store } from "./redux/store";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </Provider>
);
``` 
- Create a slicer(`src/redux/counterSlicer.jsx`) where you define actions and reducers.

```
import { createSlice } from "@reduxjs/toolkit";

// Create the initial state of the counter
const initialState = {
    counter : 0
}

// Create the slice of the state
const counterSlice = createSlice({
    // The name of the slice
    name : 'counter',
    // The initial state of the slice
    initialState,
    // The reducers of the slice
    reducers : {
        // Increment the counter by 1 when the increment action is dispatched
        incrementAction : (state) => {
            // Increment the counter by 1
            state.counter = state.counter + 1;
        },
        // Decrement the counter by 1 when the decrement action is dispatched
        decrementAction : (state) => {
            // Decrement the counter by 1
            state.counter = state.counter - 1;
        }
    }
});

// Export the actions of the slice
export const {incrementAction , decrementAction } = counterSlice.actions;
// Export the reducer of the slicel
export default counterSlice.reducer;
``` 
- Update the store.js

```
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counterSlice";

export const store = configureStore({
    reducer : {
        counter : counterReducer
    }
})
``` 
### 5. Subscribe and Dispatch events
> Subscribe to state `counter(same name as defined in store.jsx)` in App.js.

- add import statement in App.js

```
import { useSelector } from "react-redux";
``` 
- add subscriber to global state in App.js

```
  const counterStore = useSelector(state => state.counter);
``` 
- listen to state changes in App.js

```
 <div className = "col-md-2">
       <h4>
          {counterStore.counter}
        </h4>
 </div>
``` 
If you run the application now, you will see exactly like below. But the increment and decrement won't work. Don't worry it will start working soon 😃
![selector](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/00u9tif374o7vuns45dl.PNG)
> Now it's time to call actions.

- add import statements

```
import { useSelector, useDispatch } from "react-redux";
import { decrementAction, incrementAction } from "./redux/CounterSlice";
``` 
- create a dispath variable for calling actions

```
  const dispatch = useDispatch();
``` 
- call the dispath event in increment and decrement onClick

```
 <Button variant="primary" onClick = {() => dispatch(incrementAction()) }>
        Increment
  </Button>
.....
<Button variant="primary" onClick = {() => dispatch(decrementAction())}>
        Decrement
 </Button>
``` 
- Final App.js

```
import './App.css';
import React, {useState} from 'react';
import { Button } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import { useSelector, useDispatch } from "react-redux";
import { decrementAction, incrementAction } from "./redux/CounterSlice";

function App() {
  // create a state variable called counter and set it to 0
  const [counter , setCounter] = useState(0);
  const counterStore = useSelector(state => state.counter);
  // create a dispatch variable
  const dispatch = useDispatch();

  // create a function called increment that adds 1 to the counter
  const incrementCounter = () => {
    setCounter(counter + 1);
  }

  // create a function called decrement that subtracts 1 from the counter
  const decrementCounter = () => {
    setCounter(counter - 1);
  }

  return (
    <div className="App container-md pt-5">
      <div className = "pb-3">
      <h2> Simple Counter Application... 🔥 </h2>
      </div>
      <div className = "row">
        <div className = "col-md-5">
          <Button variant="primary" onClick = {() => dispatch(incrementAction()) }>
            Increment
          </Button>
        </div>
        <div className = "col-md-2">
          <h4>
            {counterStore.counter}
          </h4>
        </div>
        <div className = "col-md-5">
          <Button variant="primary" onClick = {() => dispatch(decrementAction())}>
            Decrement
          </Button>
        </div>
      </div>
    </div>
  );
}

export default App;
``` 

- Now you should see increment and decrement in action 🔥.
![dispatch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwddk9mdn9152r7vnfaw.PNG)

### 6. Final thoughts
Awesome 🔥, you have successfully completed this tutorial. I would 💝 to hear your feedback and comments on the Great things your are building with React.

If you are struck somewhere feel free to comment. I am always available.

Please find the complete code at [github](https://github.com/rahul-yr/sh-redux-toolkit-counter)