Skip to content

Commit 2c0ecd0

Browse files
authored
Merge pull request #338 from Yashgabani845/yash-work
Redux toolkit tutorial added
2 parents c1ceca1 + 768176f commit 2c0ecd0

File tree

4 files changed

+518
-0
lines changed

4 files changed

+518
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"label": "Module 16: Redux Toolkit",
3+
"position": 6,
4+
"link": {
5+
"type": "generated-index",
6+
"description": "In this module, you will learn how to create a new module using the Reduc Toolkit library and create a new module using the new module syntax and about Utilities"
7+
}
8+
}
9+
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
---
2+
id: lesson-1
3+
title: "Introduction to Redux Toolkit"
4+
sidebar_label: Lesson - 1
5+
sidebar_position: 1
6+
description: "In this lesson, you will learn the basics of Redux Toolkit, including its core concepts and how it simplifies the process of managing state in your React applications."
7+
tags:
8+
[
9+
courses,
10+
redux-toolkit,
11+
react-js,
12+
state-management,
13+
redux,
14+
introduction,
15+
]
16+
---
17+
18+
## Introduction
19+
20+
Redux Toolkit is the official, recommended way to write Redux logic. It provides a set of tools and best practices that make it easier to write Redux applications. Redux Toolkit includes utilities to simplify common use cases, such as store setup, creating reducers, and writing immutable update logic.
21+
22+
## Why Use Redux Toolkit?
23+
24+
Redux Toolkit addresses many common concerns when working with Redux:
25+
26+
1. **Boilerplate Reduction:** Simplifies the process of creating reducers, actions, and the store.
27+
2. **Immutability:** Enforces immutable state updates using Immer.
28+
3. **Efficiency:** Includes performance optimizations and simplifies common tasks.
29+
4. **Configuration:** Provides built-in middleware like Redux Thunk for handling side effects.
30+
31+
## Getting Started with Redux Toolkit
32+
33+
### 1. Installing Redux Toolkit
34+
35+
To get started with Redux Toolkit, you need to install it along with React-Redux:
36+
37+
```bash
38+
npm install @reduxjs/toolkit react-redux
39+
```
40+
41+
### 2. Creating a Redux Store
42+
43+
Redux Toolkit provides a `configureStore` function that simplifies store creation. It includes good defaults and automatically sets up the Redux DevTools extension.
44+
45+
```Javascript title="src/app/store.js"
46+
import { configureStore } from '@reduxjs/toolkit';
47+
import counterReducer from '../features/counter/counterSlice';
48+
49+
const store = configureStore({
50+
reducer: {
51+
counter: counterReducer,
52+
},
53+
});
54+
55+
export default store;
56+
```
57+
58+
### 3. Creating a Slice
59+
60+
A slice is a collection of Redux reducer logic and actions for a single feature of your app. Redux Toolkit’s `createSlice` function automatically generates action creators and action types.
61+
62+
```javascript title = "src/app/app.js"
63+
import { createSlice } from '@reduxjs/toolkit';
64+
65+
export const counterSlice = createSlice({
66+
name: 'counter',
67+
initialState: {
68+
value: 0,
69+
},
70+
reducers: {
71+
increment: (state) => {
72+
state.value += 1;
73+
},
74+
decrement: (state) => {
75+
state.value -= 1;
76+
},
77+
incrementByAmount: (state, action) => {
78+
state.value += action.payload;
79+
},
80+
},
81+
});
82+
83+
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
84+
export default counterSlice.reducer;
85+
```
86+
87+
### 4. Using the Redux Store in a React Component
88+
89+
Now that the store and slice are set up, you can use them in your React components. Use the `useSelector` hook to read state and the `useDispatch` hook to dispatch actions.
90+
91+
```javascript title = "src/features/counter/counter.js
92+
import React from 'react';
93+
import { useSelector, useDispatch } from 'react-redux';
94+
import { increment, decrement, incrementByAmount } from './counterSlice';
95+
96+
function Counter() {
97+
const count = useSelector((state) => state.counter.value);
98+
const dispatch = useDispatch();
99+
100+
return (
101+
<div>
102+
<div>
103+
<button onClick={() => dispatch(increment())}>+</button>
104+
<span>{count}</span>
105+
<button onClick={() => dispatch(decrement())}>-</button>
106+
</div>
107+
<div>
108+
<button onClick={() => dispatch(incrementByAmount(5))}>Increment by 5</button>
109+
</div>
110+
</div>
111+
);
112+
}
113+
114+
export default Counter;
115+
```
116+
117+
### 5. Providing the Redux Store to Your Application
118+
119+
To make the Redux store available to your entire app, wrap your application in the `Provider` component from `react-redux`.
120+
121+
```javascript title = "src/index.js"
122+
import React from 'react';
123+
import ReactDOM from 'react-dom';
124+
import { Provider } from 'react-redux';
125+
import store from './app/store';
126+
import App from './App';
127+
128+
ReactDOM.render(
129+
<Provider store={store}>
130+
<App />
131+
</Provider>,
132+
document.getElementById('root')
133+
);
134+
```
135+
136+
### Redux Data Flow
137+
138+
Understanding the data flow in Redux is crucial to effectively managing state in your application. The following diagram illustrates how data moves through a Redux application:
139+
140+
![Redux Data Flow Diagram](https://redux.js.org/assets/images/ReduxDataFlowDiagram-49fa8c3968371d9ef6f2a1486bd40a26.gif)
141+
142+
*Description:* This diagram demonstrates the unidirectional data flow in Redux: Actions are dispatched by components, which are then processed by reducers to update the state. The updated state is then passed to the components via the store, closing the loop.
143+
144+
### Conclusion
145+
146+
In this lesson, you learned the basics of Redux Toolkit, including how to install it, create a Redux store, define a slice, and use the Redux store in your React components. Redux Toolkit simplifies the process of working with Redux by providing utility functions and sensible defaults. Understanding the data flow in Redux will help you build more efficient and maintainable state management solutions.
147+
148+
---
149+
150+
This structured approach provides a solid foundation for managing state with Redux Toolkit, making your Redux code more concise and maintainable.
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
id: lesson-2
3+
title: "Advanced State Management with Redux Toolkit"
4+
sidebar_label: Lesson - 2
5+
sidebar_position: 2
6+
description: "In this lesson, you will learn advanced state management techniques using Redux Toolkit, including handling asynchronous actions with createAsyncThunk and managing complex state logic."
7+
tags:
8+
[
9+
courses,
10+
redux-toolkit,
11+
react-js,
12+
state-management,
13+
redux,
14+
advanced,
15+
]
16+
---
17+
18+
## Introduction
19+
20+
Creating an API utility for your application is an essential step to manage and separate concerns effectively. By centralizing your API calls, you simplify the process of managing data retrieval, error handling, and side effects, resulting in cleaner and more maintainable code. This lesson will guide you through creating an API utility and using it with Redux Toolkit to manage state in a structured and efficient way.
21+
22+
## Steps to Create an API Utility
23+
24+
### 1. Creating an API Utility
25+
26+
You'll often want to separate your API calls into a dedicated utility file. This approach allows you to centralize the logic for making HTTP requests, making your code more modular and easier to maintain.
27+
28+
```javascript title = "src/features/posts/postsAPI.js"
29+
import axios from 'axios';
30+
31+
export const fetchPosts = () => {
32+
return axios.get('https://jsonplaceholder.typicode.com/posts');
33+
};
34+
```
35+
36+
*Description:* The above code creates an API utility using Axios to fetch posts from a placeholder API. This utility function can be reused across different parts of your application wherever you need to fetch posts data.
37+
38+
### 2. Using Thunks in a Component
39+
40+
With the API utility created, you can now use it in your Redux slices to handle asynchronous actions. Redux Toolkit provides `createAsyncThunk` to simplify this process.
41+
42+
```javascript title = "src/features/posts/Posts.js"
43+
import React, { useEffect } from 'react';
44+
import { useSelector, useDispatch } from 'react-redux';
45+
import { fetchPostsAsync } from './postsSlice';
46+
47+
function Posts() {
48+
const dispatch = useDispatch();
49+
const posts = useSelector((state) => state.posts.items);
50+
const status = useSelector((state) => state.posts.status);
51+
const error = useSelector((state) => state.posts.error);
52+
53+
useEffect(() => {
54+
if (status === 'idle') {
55+
dispatch(fetchPostsAsync());
56+
}
57+
}, [status, dispatch]);
58+
59+
return (
60+
<div>
61+
{status === 'loading' && <div>Loading...</div>}
62+
{status === 'succeeded' && (
63+
<ul>
64+
{posts.map((post) => (
65+
<li key={post.id}>{post.title}</li>
66+
))}
67+
</ul>
68+
)}
69+
{status === 'failed' && <div>{error}</div>}
70+
</div>
71+
);
72+
}
73+
74+
export default Posts;
75+
```
76+
77+
*Description:* This component uses the `fetchPostsAsync` thunk to fetch posts data when the component mounts. It leverages the Redux state to manage loading, success, and error states, providing a responsive user experience.
78+
79+
![Redux Toolkit Thunks](https://i.ytimg.com/vi/e0pw9j4pi2A/maxresdefault.jpg)
80+
81+
*Description:* The image above provides a visual representation of how Redux Toolkit thunks can be used to manage asynchronous operations in your Redux state management.
82+
83+
## Managing Complex State Logic
84+
85+
For complex applications, it's important to structure your state effectively to avoid deeply nested structures. Normalizing state makes it easier to update and manage, reducing the likelihood of bugs and improving performance.
86+
87+
### 1. Normalizing State Structure
88+
89+
```javascript title = "src/features/entities/entitiesSlice.js"
90+
import { createSlice } from '@reduxjs/toolkit';
91+
92+
const entitiesSlice = createSlice({
93+
name: 'entities',
94+
initialState: {
95+
users: {},
96+
posts: {},
97+
comments: {},
98+
},
99+
reducers: {
100+
addUser: (state, action) => {
101+
const user = action.payload;
102+
state.users[user.id] = user;
103+
},
104+
addPost: (state, action) => {
105+
const post = action.payload;
106+
state.posts[post.id] = post;
107+
},
108+
addComment: (state, action) => {
109+
const comment = action.payload;
110+
state.comments[comment.id] = comment;
111+
},
112+
},
113+
});
114+
115+
export const { addUser, addPost, addComment } = entitiesSlice.actions;
116+
export default entitiesSlice.reducer;
117+
```
118+
119+
*Description:* This slice normalizes the state structure by storing users, posts, and comments in separate dictionaries indexed by their IDs. This approach allows for efficient state updates and access.
120+
121+
### 2. Using Entity Adapter
122+
123+
Redux Toolkit provides `createEntityAdapter` to manage normalized state more efficiently. It includes helpers for common operations like adding, updating, and removing entities.
124+
125+
```javascript title="src/features/posts/postsSlice.js"
126+
import { createSlice, createEntityAdapter } from '@reduxjs/toolkit';
127+
import { fetchPosts } from './postsAPI';
128+
129+
const postsAdapter = createEntityAdapter();
130+
131+
const postsSlice = createSlice({
132+
name: 'posts',
133+
initialState: postsAdapter.getInitialState({
134+
status: 'idle',
135+
error: null,
136+
}),
137+
reducers: {},
138+
extraReducers: (builder) => {
139+
builder
140+
.addCase(fetchPosts.pending, (state) => {
141+
state.status = 'loading';
142+
})
143+
.addCase(fetchPosts.fulfilled, (state, action) => {
144+
state.status = 'succeeded';
145+
postsAdapter.setAll(state, action.payload);
146+
})
147+
.addCase(fetchPosts.rejected, (state, action) => {
148+
state.status = 'failed';
149+
state.error = action.error.message;
150+
});
151+
},
152+
});
153+
154+
export const { selectAll: selectAllPosts } = postsAdapter.getSelectors(
155+
(state) => state.posts
156+
);
157+
158+
export default postsSlice.reducer;
159+
```
160+
161+
*Description:* The `postsAdapter` provides a set of pre-built reducers and selectors to manage the posts state. This approach simplifies the implementation of common CRUD operations and ensures consistent state structure.
162+
163+
## Conclusion
164+
165+
In this lesson, you learned how to create an API utility and integrate it with Redux Toolkit to manage asynchronous actions. You also explored advanced state management techniques, including normalizing state structures and using entity adapters for efficient state updates. By following these practices, you can build more robust and maintainable Redux applications.
166+
167+
---
168+
169+
This approach to advanced state management with Redux Toolkit ensures your application remains scalable and maintainable as it grows in complexity.

0 commit comments

Comments
 (0)