DEV Community

Cover image for Intro to Redux-Toolkit
Sarthak Pant
Sarthak Pant

Posted on

Intro to Redux-Toolkit

Introduction

First, let's start with what is Redux.

Redux

Redux is a state management library. Redux make it easy to debug and is used when we need consistency.

Why we need Redux Toolkit then?

Redux Toolkit does the same thing as redux do, that is to make our life more easier and simpler.
Redux toolkit includes utilities that helps to simplify many common use cases, including store setup, creating reducers and writing immutable update logic, and even creating entire "slices" of state at once. All of these term would be explained below.

Let me explain the use of redux toolkit with a simple example.

Example

Lets say you are making an eCommerce website using react.Now u know that in react we use components.Lets say that you have made a website as shown below. 👇

Image description

Now the nav bar is in different component and your product list is in different component.Lets say that you have added a product to the cart.So how do u think that other component knows what thing have changed in other component.Such changes are solved by the use of any state management libraries.Here we are using Redux Toolkit.
So lets get started. ✨

Basic Terminologies

  • redux store: A store is a state container which holds the application's state
  • redux slice: A slice is the portion of Redux code that relates to a specific set of data and actions within the store 's state.
  • createAsyncThunk: Handles all async function that we will create.
  • createReducer():A utility that simplifies creating Redux reducer functions.

Let's redux

Create a react app

#npm

npx create-react-app learnredux
cd learnredux

#yarn
yarn add create-react-app learnredux
Enter fullscreen mode Exit fullscreen mode

Install redux-toolkit

#npm

npm install react-redux
npm install @reduxjs/toolkit

#yarn

yarn add react-redux
yarn add @reduxjs/toolkit
Enter fullscreen mode Exit fullscreen mode

Setup

  • Start by making app folder which will have store
mkdir app
Enter fullscreen mode Exit fullscreen mode

Now make a store.js in this we will be having all our reducers.

Initialize it with this(./src/app/store.js)

import { configureStore, createReducer } from '@reduxjs/toolkit'
export const store = configureStore({
  reducer: {
  },
})

Enter fullscreen mode Exit fullscreen mode
  • Make a new folder named features in which we would have all our slices.(./src)
mkdir features
Enter fullscreen mode Exit fullscreen mode

Let's make our first slice. Get inside features folder and then make a new folder named counter.(./src/features)

mkdir counter
cd counter
Enter fullscreen mode Exit fullscreen mode

Make counterSlice.js inside counter folder (./src/features/counter).
inside this slice add this piece of code

import { createSlice } from '@reduxjs/toolkit'

const initialState = {
  count: 0,
}

export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.count += 1
    },
    decrement: (state) => {
      state.count -= 1
    },
    reset: (state) => {
      state.count = 0
    },
    incrementByAmmount: (state, action) => {
      state.count += action.payload
    },
  },
})

export const {
  increment,
  decrement,
  reset,
  incrementByAmmount,
} = counterSlice.actions

export default counterSlice.reducer

Enter fullscreen mode Exit fullscreen mode

So if u see this code we are first making our initial state. You can think of this like whenever we reload, the current state will change to its initial State.
Then you can see CounterSlice in this first we will declare a name of this slice then the start state (initial state), then we have to make our reducers.Reducer: (change the state of your slice).At the end we are exporting them out.

  • Now go to (./src/app/store) and add this.
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'
export const store = configureStore({
  reducer: { counter: counterReducer },
})

Enter fullscreen mode Exit fullscreen mode

Even after adding the reducer, reducer cannot be used.
For that we need to declare it inside Provider.This is what we are going to do next.

  • Go to index.js and then add Provider and store.
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { store } from './app/store';
import { Provider } from 'react-redux';


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
    <App />
    </Provider>
  </React.StrictMode>
);

Enter fullscreen mode Exit fullscreen mode

This will make reducer globally accessible.

  • Make one component and add these things.
import React, { useState } from 'react'
from './counterSlice'
const Counter = () => {


  const [incrementAmmount, setIncrementAmmount] = useState(0)


  return (
    <section>
      <p>0</p>
      <div>
        <button }>+</button>
        <button }>-</button>

      </div>
      <input
        type="text"
        value={incrementAmmount}
        }
      />
      <div>
        <button >
          Add ammount
        </button>
        <button >reset</button>
      </div>
    </section>
  )
}

export default Counter

Enter fullscreen mode Exit fullscreen mode

This is the stater coder We are only focusing on redux-toolkit and not focusing on css.

Now we earlier in our counterSlice we have made multiple reducer and initial state.
Lets start bringing them on this component.

Add this to our Counter.js

const count = useSelector((state) => state.counter.count)
Enter fullscreen mode Exit fullscreen mode

useSelector() selects any element that is declared on our initial state.

Now lets add function that we have created to our button using dispatch()

On + button make it like this.

 <button onClick={() => dispatch(increment())}>+</button>
Enter fullscreen mode Exit fullscreen mode

This will make sure that whenever you click on add button it will call increment() using dispatch. So you can say that dispatch is help us call all the function that we have made on our slice.

Try doing - and reset on your own.

Lets do add ammount.

 <button onClick={() => dispatch(incrementByAmmount(addValue))}>
          Add ammount
        </button>
Enter fullscreen mode Exit fullscreen mode

It takes ammount from our input variable and then sends the value to our reducer.

So our whole Counter.js should look like this.

import React, { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { increment, decrement, reset, incrementByAmmount } from './counterSlice'
const Counter = () => {
  const count = useSelector((state) => state.counter.count)
  const dispatch = useDispatch()
  const [incrementAmmount, setIncrementAmmount] = useState(0)

  const addValue = Number(incrementAmmount) || 0

  const resetAll = () => {
    setIncrementAmmount(0)
    dispatch(reset())
  }
  return (
    <section>
      <p>{count}</p>
      <div>
        <button onClick={() => dispatch(increment())}>+</button>
        <button onClick={() => dispatch(decrement())}>-</button>

      </div>
      <input
        type="text"
        value={incrementAmmount}
        onChange={(e) => setIncrementAmmount(e.target.value)}
      />
      <div>
        <button onClick={() => dispatch(incrementByAmmount(addValue))}>
          Add ammount
        </button>
        <button onClick={resetAll}>reset</button>
      </div>
    </section>
  )
}

export default Counter

Enter fullscreen mode Exit fullscreen mode

And it should look like this.

Image description

Conclusion

Redux toolkit will make our life easier. Tough it's kind of confusing at first but once you get the hang of it you would be able to use it easy and efficiently.
I will be making uploading another post about handling async function. And will try to upload a video about it asap.

Top comments (1)

Collapse
 
aasthagarg128 profile image
aasthagarg128

extremely helpful sir !!!!!