Reddit Project: Cant seem to render data to UI

Hi Guys, Am struggling to render the API data from reddit to the UI, not sure where am going wrong as am still pretty new to coding.
i can see there is data fetch from the api using Redux tool, but i just cant seem to get it to render it.
am not sure if am using the right approach? Please anyone with Kind pair of extra eyes look at code, Much Appreciated.

RedditSlice.js


import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";
import { createAsyncThunk } from "@reduxjs/toolkit";


export const fetchPosts = createAsyncThunk('post/fetchPosts', async () => {
  try {
  const response = await axios
    .get('https://www.reddit.com/r/popular.json');
  return response.data;
  }catch (error) {
    throw error;
  }
});

const initialState = {
  loading: false,
  posts: [],
  error: '',
}

const RedditPostsSlice = createSlice({
  name: 'posts',
  initialState,
  reducers: (builder) => {
    builder.addCase(fetchPosts.pending, (state) => {
      state.loading = true;
      state.error = '';
    })
    builder.addCase(fetchPosts.fulfilled, (state, action) => {
      state.loading = false;
      state.posts = action.payload;
      state.error = '';
    })
    builder.addCase(fetchPosts.rejected, (state, action) => {
      state.loading = false;
      state.posts = [];
      state.error = action.error.message;
    })
}})

export default RedditPostsSlice.reducer;

Store.js

import { configureStore, combineReducers } from "@reduxjs/toolkit";
import RedditPostsSlice from "./RedditSlice";

export default configureStore({
    reducer: combineReducers({
       posts: RedditPostsSlice
    })
});

Posts.js

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { useEffect } from "react";
import { fetchPosts } from "../../API/RedditSlice";


const Posts = () => {    
    const post = useSelector((state) => state.posts);
    const dispatch = useDispatch();

    useEffect(() => {
        console.log('Component mounted');
        console.log('Received post data:', post);
      dispatch(fetchPosts())
    }, [dispatch]);

    return (
        <div className="card">              
            <h2>List of Posts</h2>  
                {post.loading && <div>Loading...</div>}
                {!post.loading && post.error ? (
                    <div>ERROR: {post.error}</div>
                    ) : null}
                {!post.loading && post.posts.length ? (
                <ul>            
                    {post.Posts.map((post) => (
                    <li key={post.kind}>
                        {post.data.children[0]}
                    </li>
                    ))}
                </ul>
            ) : null}
        </div>      
    )
}

export default Posts;

App.js

import React from 'react'
import './App.css';
import Header from '../Components/Header/Header';
import Posts from '../Components/Posts/Posts';


function App() {
  return (
    <>
      <Header />
      <main>
        <Posts />
      </main> 
    </>               
  );
}

export default App;

Thanks in Advance!!!

In the Redux DevTools, go to the “State” tab - what is the state of Posts in RedditPostsSlice?

Looking at the payload, it looks like you want to return response.data.children instead of just response.data

Hi @jameskeezer, thanks for the quick response,
i have added children to response but i seem to have no response.
here a img of my state.

i feel that it might be my Posts.js file which i might render it wrongly.

It appears that the posts are not being added to state here. If you click on the bottom action post/fetchPosts/fulfilled does it show anything in state.posts.posts?

Try it out with both response.data and response.data.children and see if either of them successfully add the posts to the array in state.

I just noticed as well, in RedditSlice.js you’ll need to export state.posts.posts to use with useSelector()

export const posts = (state) => state.reddit.posts;

then in Posts.js

import { posts } from './RedditSlice'

That may not totally solve the issue, but it should get you on your way :+1:

Hi @jameskeezer,
i’ve manage to fetch data to the array by adding another data,

return response.data.data.children.map((post) => post.data);

somehow that works? am currently displaying title to my UI, but i cant seem to implement the image(thumbnail) and post content all together. going to try create another component to handle all that, then export it out.
any advice or tips? appreciate your help so far.

Well done! Keep going, you are on the right path.

When in doubt, console.log everything. You’re using the DevTools and that’s great. Really get used to them, because they are invaluable (actually… necessary!) when debugging.

When you know exactly where to look, you will save so much time and you can just focus on building.

console.log out each post object (or just look at each post in state in your Redux DevTools!) and look at the keys & values. You will find what you need.

thank you for your great support!! i’ve actually got the post up with css now, now need to implement the score board and comment section to the post, i appreciate your time and support, but this won’t be the end of me asking for help…lol

1 Like

Hi @jameskeezer,
sorry to trouble you again, am find it hard to get state for my comments endpoint, state has a empty array when return. not sure am going wrong? first time round i had issue with CORS denied my access, so i had to do it again as i do not know how to bypass it through backend server.
this time round there no error message about CORS, but do you think it still could be the case?
heres my fetch code:

import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";
import { createAsyncThunk } from "@reduxjs/toolkit";

 export const fetchComments = createAsyncThunk('posts/fetchComments', async (permalink) => {
     try {
     const response = await axios
       .get(`https://www.reddit.com/r/${permalink}.json`);
     return response.data[1].data.children.map((comment) => comment.data);
     }catch (error) {
       throw (error);
     }
  });

  //create slice & reducer
const RedditCommentsSlice = createSlice({
    name: 'redditComments',
    initialState: {
      loading: false,
      error: false,
      comments: [],
  
    },
    reducers: {
      fetchCommentsPending: (state) => {
        state.loading = true;
        state.error = false;
      },
      fetchCommentsFulfilled: (state, action) => {
        state.loading = false;
        state.comments = action.payload;
      },
      fetchCommentsRejected: (state, action) => {
        state.loading = false;
        state.error = action.error;
      },
    },
})
  
  export const { fetchCommentsPending, fetchCommentsFulfilled, fetchCommentsRejected } = RedditCommentsSlice.actions;
  export default RedditCommentsSlice.reducer;

also a image of state.

many thanks.