Introduction
Redux Toolkit is a package that simplifies and streamlines the usage of Redux, a popular state management library for JavaScript applications. Redux Toolkit provides a set of tools and abstractions that make it easier to write Redux code with fewer lines and less boilerplate. It encourages best practices and helps developers write more maintainable and efficient Redux code.
Some key features and concepts of Redux Toolkit include:
Redux Store Configuration: Redux Toolkit provides a
configureStore()
function, which combines several Redux store setup steps into a single function call. It sets up the Redux store with sensible defaults and includes built-in middleware, such as Redux Thunk for async actions.Simplified Reducer Logic: Redux Toolkit introduces a
createSlice()
function that reduces the amount of boilerplate required to define reducers. It generates action creators and action types automatically based on the provided reducer function.Immutable Updates: Redux Toolkit uses an optimized version of the Immer library under the hood to handle immutable updates to the Redux store. With Immer, you can write "mutating" code that looks like regular JavaScript, but it creates a new immutable state behind the scenes.
DevTools Configuration: Redux Toolkit automatically sets up integration with the Redux DevTools Extension, a browser extension that provides advanced debugging and time-traveling capabilities for Redux.
Additional Utilities: Redux Toolkit includes additional utilities like
createAsyncThunk()
for handling asynchronous actions,createEntityAdapter()
for managing normalized data, andcreateSelector()
for efficient and memoized data selection.
Installing Redux
To install Redux in a React project, you can follow these steps:
Create a new React project using
create-react-app
or navigate to your existing React project directory.Open your terminal or command prompt and navigate to the project directory.
Run the following command to install Redux and its dependencies via npm (Node Package Manager):
npm install redux react-redux
Alternatively, if you're using Yarn, you can use the following command:
yarn add redux react-redux
This command will install Redux and React Redux and add them as dependencies in your project's
package.json
file.
Installing RTK
To install Redux Toolkit (RTK) in your JavaScript project, you need to follow these steps:
Create a new JavaScript project or navigate to your existing project directory in your terminal.
Run the following command to install Redux Toolkit via npm (Node Package Manager):
npm install @reduxjs/toolkit
Alternatively, if you're using Yarn, you can use the following command:
yarn add @reduxjs/toolkit
This command will install Redux Toolkit and add it as a dependency in your project's
package.json
file.
General Work Flow of State Management in RTK
Let us Consider an example to further understand the workflow
Suppose we want to change the state when an item is selected and we want to put that item in the cart is pressed
We will first configure a store redux toolkit which will be imported from the redux toolkit.
In that store we will create different slices, it is these slices in which the update will be performed
On the click of the add button which will help us to add an item to the cart, we will dispatch an action
After the action is dispatched it will call a reducer.A reducer is basically a function that will perform the adding operation to the cart
Remember our cart is basically a slice and it is the slice that has the reducer
How to create a slice
To create a slice in Redux using Redux Toolkit, you can follow these steps:
Import necessary Redux Toolkit functions and utilities:
import { createSlice } from '@reduxjs/toolkit';
Define the initial state for your slice:
const initialState = { count: 0, isLoading: false, error: null, };
Create the slice using the
createSlice()
function:const counterSlice = createSlice({ name: 'counter', initialState, reducers: { increment: (state) => { state.count += 1; }, decrement: (state) => { state.count -= 1; }, setCount: (state, action) => { state.count = action.payload; }, setLoading: (state, action) => { state.isLoading = action.payload; }, setError: (state, action) => { state.error = action.payload; }, }, });
In the example above, we created a slice named
'counter'
with the initial state defined earlier. Inside thereducers
object, we defined several action reducers. Each reducer function receives the current state as the first argument and the action as the second argument. The reducer functions directly modify the state because Redux Toolkit uses Immer under the hood, allowing you to write "mutating" code.Export the generated action creators and the reducer:
export const { increment, decrement, setCount, setLoading, setError } = counterSlice.actions; export default counterSlice.reducer;
By exporting the generated action creators (
increment
,decrement
, etc.) and the reducer (counterSlice.reducer
), you can easily use them in other parts of your application.
Configuring Our Store
import { configureStore } from '@reduxjs/toolkit'; import rootReducer from './reducers'; const store = configureStore({ reducer: { name: {userSlice.reducer} }, // ... Additional configuration options }); export default store;
Provider tag indicates which all components should have access to the global storage
Dispatching the action
In Redux,
useDispatch()
is a hook provided by React Redux that allows you to access thedispatch
function from the Redux store. You can use it in your functional components to dispatch actions and trigger state updates. Here's an example of how to useuseDispatch()
:Import the necessary dependencies:
import { useDispatch } from 'react-redux'; import { increment, decrement } from './actions'; // Import your action creators
Inside your functional component, call
useDispatch()
to get thedispatch
function:const dispatch = useDispatch();
Use the
dispatch
function to dispatch actions when needed:dispatch(increment()); // Dispatch the increment action dispatch(decrement()); // Dispatch the decrement action
In the example above, we dispatched actions created by the
increment
anddecrement
action creators. These action creators are functions that return action objects, which have atype
property and optionally apayload
property.
Here's a complete example demonstrating the usage of useDispatch()
:
import React from 'react';
import { useDispatch } from 'react-redux';
import { increment, decrement } from './actions'; // Import your action creators
function Counter() {
const dispatch = useDispatch();
const handleIncrement = () => {
dispatch(increment()); // Dispatch the increment action
};
const handleDecrement = () => {
dispatch(decrement()); // Dispatch the decrement action
};
return (
<div>
<button onClick={handleIncrement}>Increment</button>
<button onClick={handleDecrement}>Decrement</button>
</div>
);
}
export default Counter;
In the example above, we imported the useDispatch
hook from react-redux
and the increment
and decrement
action creators from your custom actions
file. Inside the Counter
component, we used useDispatch()
to get the dispatch
function, and then defined event handlers (handleIncrement
and handleDecrement
) that dispatch the respective actions when the buttons are clicked.
Using useDispatch()
allows you to access the dispatch
function in your functional components and dispatch actions to update the Redux store state.
How to access the values for this we use a USEselector
In Redux,
useSelector()
is a hook provided by React Redux that allows you to extract and access specific values from the Redux store state. It allows you to subscribe to changes in the Redux store and retrieve the selected data in your functional components. Here's an example of how to useuseSelector()
:Import the necessary dependencies:
import { useSelector } from 'react-redux';
Inside your functional component, call
useSelector()
to select and retrieve the desired state value:const count = useSelector(state => state.counter.count);
In the example above, we're using an arrow function inside
useSelector()
. The function takes the complete Redux store state as an argument and returns the selected value, which in this case isstate.counter.count
.state.counter
corresponds to the slice name, andcount
corresponds to the property within that slice.Use the selected value in your component:
return ( <div> <p>Count: {count}</p> </div> );
In this example, we're rendering the selected
count
value within a paragraph tag.
Here's a complete example demonstrating the usage of useSelector()
:
import React from 'react';
import { useSelector } from 'react-redux';
function CounterDisplay() {
const count = useSelector(state => state.counter.count);
return (
<div>
<p>Count: {count}</p>
</div>
);
}
export default CounterDisplay;
In the example above, we imported the useSelector
hook from react-redux
. Inside the CounterDisplay
component, we used useSelector()
to select the count
value from the counter
slice of the Redux store state. We then rendered the selected count
value within a paragraph tag.
By using useSelector()
, you can access specific values from the Redux store state and automatically update your component whenever those values change. This allows you to efficiently retrieve and display relevant data from the Redux store in your functional components.