useSelector returning undefined

84 Views Asked by At

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: enter image description here

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

What am I missing? Thanks in advance.

1

There are 1 best solutions below

0
Sam On

In your store.js file you have named your reducer slice as fetch:

export default configureStore({
    reducer: {
        fetch: fetchReducer,
    },
});

However, in your Posts.js file, you are attempting to get the posts from the state:

const posts  = useSelector((state) => state.posts);

This does not line up with the name you have assigned in the store.

Change your useSelector in Posts.js to match what you've defined in store.js:

const posts = useSelector((state) => state.fetch);

That should fix your issue.