Here is all ok, response.data is array:
export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => {
const response = await axios.get('https://640114a00a2a1afebee5c77d.mockapi.io/post1')
console.log(response)
return response.data
})
Here is not, state is empty:
useEffect(() => {
console.log(postStatus)
if (postStatus === 'idle') {
dispatch(fetchPosts())
}
}, [postStatus, dispatch])
I try to use thunk in React Redux app with data on Mock server.
PostsList.js:
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { selectAllPosts, fetchPosts } from './postsSlice'
import { Spinner } from '../../components/Spinner'
const PostExcerpt = ({ post }) => {
return (
<article className="post-excerpt" key={post.id}>
<h3>{post.title}</h3>
<p className="post-content">{post.content.substring(0, 100)}
</p>
</article>
)
}
export const PostsList = () => {
const dispatch = useDispatch()
const posts = useSelector(selectAllPosts)
console.log(posts)
const postStatus = useSelector((state) => state.posts.status)
const error = useSelector((state) => state.posts.error)
console.log(posts)
useEffect(() => {
console.log(postStatus)
if (postStatus === 'idle') {
dispatch(fetchPosts())
}
}, [postStatus, dispatch])
let content
if (postStatus === 'loading') {
content = <Spinner text="Loading..." />
} else if (postStatus === 'succeeded') {
content = posts.map(post => (
<PostExcerpt key={post.id} post={post} />
))
} else if (postStatus === 'failed') {
content = <div>{error}</div>
}
console.log(content)
return (
<section>
<h2>Posts</h2>
{content}
</section>
)
}
postsSlice.js:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import axios from 'axios'
const initialState = {
posts: [],
status: 'idle',
error: null,
}
export const fetchPosts = createAsyncThunk('posts/fetchPosts', async ()
=> {
const response = await
axios.get('https://640114a00a2a1afebee5c77d.mockapi.io/post1')
//console.log(response)
console.log('fetchPosts response:', response)
return response.data
})
console.log(fetchPosts)
export const addNewPost = createAsyncThunk(
'posts/addNewPost',
// The payload creator receives the partial `{title, content, user}`
object
async (initialPost) => {
// We send the initial data to the fake API server
const response = await
axios.post('https://640114a00a2a1afebee5c77d.mockapi.io/post1',
initialPost)
// The response includes the complete post object, including unique
ID
return response.data
}
)
const postsSlice = createSlice({
name: 'posts',
initialState,
reducers: {
extraReducers(builder) {
builder
.addCase(fetchPosts.pending, (state) => {
state.status = 'loading'
})
.addCase(fetchPosts.fulfilled, (state, action) => {
state.status = 'succeeded'
// Add any fetched posts to the array
state.posts = state.posts.concat(action.payload)
})
.addCase(fetchPosts.rejected, (state, action) => {
state.status = 'failed'
state.error = action.error.message
})
.addCase(addNewPost.fulfilled, (state, action) => {
// We can directly add the new post object to our posts array
state.posts.push(action.payload)
})
}
}
})
export default postsSlice.reducer
export const selectAllPosts = state => state.posts.posts
console.log(selectAllPosts)
export const selectPostById = (state, postId) =>
state.posts.posts.find(post => post.id === postId)
I have been learning this https://redux.js.org/tutorials/essentials/part-5-async-logic There is local server, I use Mock server endpoint.
store.js:
import { configureStore } from '@reduxjs/toolkit';
import postsReducer from '../features/posts/postsSlice'
export const store = configureStore({
reducer: {
posts: postsReducer
}
})
console.log(store.getState())
In postsSlice.js after the word reducer and the colon there is an open curly bracket that I did not close and put a comma after it.
This is correct reducers: { },