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. 👇
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
Install redux-toolkit
#npm
npm install react-redux
npm install @reduxjs/toolkit
#yarn
yarn add react-redux
yarn add @reduxjs/toolkit
Setup
- Start by making app folder which will have store
mkdir app
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: {
},
})
- Make a new folder named features in which we would have all our slices.(
./src
)
mkdir features
Let's make our first slice. Get inside features folder and then make a new folder named counter.(./src/features
)
mkdir counter
cd counter
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
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 },
})
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>
);
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
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)
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>
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>
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
And it should look like this.
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)
extremely helpful sir !!!!!