Complete Redux Toolkit - Async Logic with(Part -2)

王林
Release: 2024-09-10 11:04:33
Original
784 people have browsed it

Complete Redux Toolkit - Async Logic with(Part -2)

1. Introduction to Async Logic in Redux Toolkit

Handling asynchronous logic in Redux often involves a lot of boilerplate code, such as creating action types, action creators, and reducers to handle different states (loading, success, error). Redux Toolkit simplifies this with createAsyncThunk, which allows you to define a "thunk" for asynchronous operations with minimal setup.

createAsyncThunk:

  • Automatically generates pending, fulfilled, and rejected action types.
  • Makes it easier to handle side effects like API requests.
  • Integrates seamlessly with slices created using createSlice.

2. Using createAsyncThunk for API Calls

Let's walk through creating an async thunk to fetch data from a public API and manage different loading states.

Step 1: Setting Up a Simple API Service
We'll use a free public API to demonstrate this example. Let's assume we have an API endpoint that returns a list of posts.

Step 2: Creating an Async Thunk
First, create a new slice file named postsSlice.js inside the features/posts directory. We'll use createAsyncThunk to fetch posts asynchronously.

// src/features/posts/postsSlice.js import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; // Async thunk to fetch posts from an API export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => { const response = await fetch('https://jsonplaceholder.typicode.com/posts'); const data = await response.json(); return data; // This will be the 'fulfilled' action payload }); const postsSlice = createSlice({ name: 'posts', initialState: { posts: [], status: 'idle', // idle | loading | succeeded | failed error: null, }, reducers: { // Optional: add reducers for synchronous actions }, extraReducers: (builder) => { builder .addCase(fetchPosts.pending, (state) => { state.status = 'loading'; }) .addCase(fetchPosts.fulfilled, (state, action) => { state.status = 'succeeded'; state.posts = action.payload; }) .addCase(fetchPosts.rejected, (state, action) => { state.status = 'failed'; state.error = action.error.message; }); }, }); export default postsSlice.reducer;
Copy after login

Explanation:

createAsyncThunk: This function takes two arguments: a string action type and an asynchronous function. The async function is where the API call happens. When the promise resolves, the data is returned and automatically dispatched as the fulfilled action payload.

extraReducers: This is used to handle actions generated by createAsyncThunk. We manage three states: pending, fulfilled, and rejected.

3. Integrating Thunks into Components

Now, let's use the fetchPosts thunk in a React component and display the data.

Step 1: Create a PostsList Component
Create a PostsList.js component in the features/posts directory:

// src/features/posts/PostsList.js import React, { useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { fetchPosts } from './postsSlice'; const PostsList = () => { const dispatch = useDispatch(); const posts = useSelector((state) => state.posts.posts); const status = useSelector((state) => state.posts.status); const error = useSelector((state) => state.posts.error); useEffect(() => { if (status === 'idle') { dispatch(fetchPosts()); } }, [status, dispatch]); let content; if (status === 'loading') { content = 

Loading...

; } else if (status === 'succeeded') { content = (
    {posts.map((post) => (
  • {post.title}
  • ))}
); } else if (status === 'failed') { content =

{error}

; } return (

Posts

{content}
); }; export default PostsList;
Copy after login

Explanation:

The useEffect hook dispatches fetchPosts when the component mounts, but only if the current status is 'idle'.
The status is checked to determine which content to render (loading spinner, list of posts, or error message).

Step 2: Add PostsList to the App

Update the main App.js file to include the PostsList component:

// src/App.js import React from 'react'; import PostsList from './features/posts/PostsList'; function App() { return ( 
); } export default App;
Copy after login

4. Best Practices for Async Thunks

Avoid Heavy Logic in Components: Keep components clean by dispatching thunks to handle asynchronous logic.
Centralize Error Handling: Handle errors in your slice rather than repeating logic in each component.
Normalize Data: Consider normalizing state shape using libraries like normalizr to manage complex data structures efficiently.
Memoize Selectors: Use createSelector from reselect to memoize selectors for better performance.

5. Conclusion and Next Steps
In this part, we explored how to handle asynchronous logic in Redux Toolkit using createAsyncThunk. We learned how to create an async thunk, handle different states, and use it in a component. In the next part, we'll dive into RTK Query—a powerful tool for data fetching and caching that further simplifies Redux development.

_
Stay tuned for Part 3: Introduction to RTK Query!_

The above is the detailed content of Complete Redux Toolkit - Async Logic with(Part -2). For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!