reduxjs/toolkit async Thunk



大家好,我是React的新手,刚刚学习用于应用程序状态管理的redujs/toolkit。我创建了一个简单的应用程序来处理帖子。目前我正在做的是使用名为fetchPosts的异步Thunk加载帖子列表。我的异步thunk在应用程序加载时被调用了两次,我真的不知道是怎么回事。我使用的是react版本18.2.0,这是我的文章片段。

import { createAsyncThunk, createSlice, nanoid } from "@reduxjs/toolkit";
import {sub} from 'date-fns';
import axios from 'axios';
const POST_URL = 'http://jsonplaceholder.typicode.com/posts';

const initialState = {
posts : [],
status : 'idle',
error : null     
};
export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => {
const response = await axios.get(POST_URL);
return response.data;
});
const postsSlice = createSlice({
name: 'posts',
initialState,
reducers:{
postAdded: {
reducer(state, action) {
state.posts.push(action.payload);
},
prepare(title,content, userId){
return {
payload:{
id: nanoid(),
title,
content,
userId,
date: new Date().toISOString(),
reactions: {
thumbsUp: 0,
wow:0,
heart:0,
rocket:0,
coffee:0
}
}
}
}
},
reactionAdded(state, action) {
const {postId, reaction} = action.payload;
const existingPost = state.posts.find(post => post.id === postId);
if (existingPost) {
existingPost.reactions[reaction]++;
}
}
},
extraReducers(builder){
builder.addCase(fetchPosts.pending, (state, action) => {
state.status = 'loading';

})
.addCase(fetchPosts.fulfilled, (state, action) => {
state.status = 'succeeded';
let min = 1;
const loadedPosts = action.payload.map(post => 
{
post.date = sub(new Date(), {minutes: min++}).toISOString();
post.reactions = {
thumbsUp: 0,
wow: 0,
heart:0,
rocket:0,
coffee:0
}
return post;
});
state.posts = loadedPosts;
})
.addCase(fetchPosts.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message
})
}
});
export const {postAdded,reactionAdded} = postsSlice.actions;
export const selectAllPosts = (state) => state.posts.posts;
export const getPostsStatus = (state) => state.posts.status;
export const getPostsError = (state) => state.posts.error;
export default postsSlice.reducer;

这是我的帖子列表组件。

import React from 'react'
import { useSelector, useDispatch } from 'react-redux';
import { selectAllPosts, getPostsError, getPostsStatus, fetchPosts } from './postsSlice';
import { useEffect } from 'react';
import PostExcerpt from './PostExcerpt';
const PostsList = () => {
const dispatch = useDispatch();
const posts = useSelector(selectAllPosts);
const postStatus = useSelector(getPostsStatus);
const postError = useSelector(getPostsError);

useEffect(() => {
console.log('post status: ', postStatus);
if(postStatus === 'idle')
{
dispatch(fetchPosts());
}
},[postStatus])
let content;
if(postStatus === 'loading'){
console.log('loading');
content = <p>"Loading..."</p>
}
else if(postStatus === 'succeeded'){
console.log('succeded');
const orderedPosts = posts.slice().sort((a,b) => b.date.localeCompare(a.date));
content = orderedPosts.map(post => <PostExcerpt key={post.id} post={post}/>);
}
else if (postStatus === 'failed'){
content = <p>{postError}</p>;
}
return (
<section>
<h2>Posts</h2>
{content}
</section>
);
}
export default PostsList

所以发生这种情况是由于装载->卸载->react版本18中实现的组件的重新装载行为useEffect。

最新更新