I am new to Redux and I am following some tutorials where the application that we are building is to create some posts.
What I am facing is that when I use useSelector, this hook is returning undefined even though the state is fulfilled and the payload exists.
Component Posts.js
import React from "react";
import { useSelector } from "react-redux/";
import Post from "./Post/Post";
const Posts = () => {
const posts = useSelector((state) => state.posts);
console.log("POSTS FROM STATE: ", posts);
return (
<>
<h1>POSTS</h1>
<Post />
<Post />
</>
);
}
export default Posts;
store.js
import { configureStore } from "@reduxjs/toolkit";
import fetchReducer from "./fetchSlice";
export default configureStore({
reducer: {
fetch: fetchReducer,
},
});
fetchSlice.js
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
export const getPostsAsync = createAsyncThunk(
'posts/getPostsAsync',
async () => {
try {
const resp = await fetch('http://localhost:5000/posts');
console.log("response: ", resp);
if (resp.ok) {
const posts = await resp.json();
console.log("resp json: ", posts);
return { posts };
}
} catch(error) {
console.log(error);
};
}
);
export const fetchSlice = createSlice({
name: 'posts',
initialState: [],
reducers: {
fetchAll: (state, action) => {
return action.payload.posts;
},
create: (state, action) => {
return
},
},
extraReducers: (builder) => {
console.log("extra builder");
builder
.addCase(getPostsAsync.pending, (state) => {
console.log("Request pending");
})
.addCase(getPostsAsync.rejected, (state) => {
console.log("Request rejected");
})
.addCase(getPostsAsync.fulfilled, (state, action) => {
console.log("Fulfilled, reducer payload: ", action.payload.posts);
return action.payload.posts;
})
}
});
export const { fetchAll, create } = fetchSlice.actions;
export default fetchSlice.reducer;
App.js
import React, { useEffect } from "react";
import { Container, AppBar, Typography, Grow, Grid, ThemeProvider } from "@mui/material";
import { useDispatch } from "react-redux";
import Posts from "./components/Posts/Posts";
import Form from "./components/Form/Form";
import memories from "./images/memories.png";
import { getPostsAsync } from "./redux/fetchSlice";
import { theme } from "./styles";
const App = () => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(getPostsAsync());
}, [dispatch]);
return (
<Container maxwidth="lg">
<ThemeProvider theme={theme}>
<AppBar sx={theme.appBar} position="static" color="inherit">
<Typography sx={theme.heading} variant="h2" align="center">Memories</Typography>
<img sx={theme.image} src={memories} alt="memories" height="60" />
</AppBar>
<Grow>
<Container>
<Grid container justify="space-between" alignItems="stretch" spacing={3}>
<Grid item xs={12} sm={7}>
<Posts />
</Grid>
<Grid item xs={12} sm={4}>
<Form />
</Grid>
</Grid>
</Container>
</Grow>
</ThemeProvider>
</Container>
);
}
export default App;
I can see in the redux store that the payload exists:

However, when I try to console log the parameter that I am using for the useSelector, it returns undefined:

What am I missing? Thanks in advance.
In your
store.jsfile you have named your reducer slice asfetch:However, in your
Posts.jsfile, you are attempting to get the posts from thestate:This does not line up with the name you have assigned in the store.
Change your
useSelectorinPosts.jsto match what you've defined instore.js:That should fix your issue.