Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

103
Views
I can't render the API I fetched with createAsyncThunk when I refresh the page

When I first open the app it gets the data from api but when I refresh the page it says Cannot read properties of undefined (reading 'memes'). When I console.log the store item It shows an empty object but I can see the api with Redux Devtools extension. I got stuck with this problem and can't figure it out for two days.

slice.js

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

export const fetchJson = createAsyncThunk(
  "json/fetchJson",
  async () => {
    const data = await fetch("https://api.imgflip.com/get_memes");
    const json = await data.json();
    return json;
  }
);


export const loadJsonSlice = createSlice({
  name: "loadJson",
  initialState: {
    isLoading: false,
    hasError: false,
    memes:{}
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchJson.pending, (state) => {
        state.isLoading = true;
        state.hasError = false;
      })
      .addCase(fetchJson.fulfilled, (state, action) => {
        state.isLoading = false;
        state.memes = action.payload;
      })
      .addCase(fetchJson.rejected, (state, action) => {
        state.isLoading = false;
        state.hasError = true;
        state.memes = {};
      });
  }
});

export default loadJsonSlice.reducer;

export const selectAllJson = (state) => state.loadJsonReducer.memes;

export const isLoading = (state) => state.loadJsonReducer.isLoading;

display.js

import { useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { selectAllJson, isLoading, fetchJson } from "./jsonSlice";
const DisplayJson = () => {
  const allMemes = useSelector(selectAllJson);
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(fetchJson());
    console.log(allMemes.data.memes[0].id); //Here is where the code gives error.
  }, [dispatch]);

  if (useSelector(isLoading)) {
    return <h1 style={{ fontSize: "48px" }}>WAIT PUST</h1>;
  }
  return <div>{allMemes.data.memes[0].id}</div>; //Here is where the code gives error.
};
export default DisplayJson;

store.js

import { configureStore } from "@reduxjs/toolkit";
import loadJsonSlice from "./jsonSlice";
const store = configureStore({
  reducer: {
    loadJsonReducer: loadJsonSlice
  }
});
export default store;

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

I believe you have a small miss-understanding of how asynchronicity works in JavaScript.

Your code in the slide.js is correct and will work.

However, your display.js has to wait for the asynchronous action to complete before it can access the state.


useEffect(() => {
    // This dispatch will return a Promise, only after the promise resolves  you can access the data
    dispatch(fetchJson());
    console.log(allMemes.data.memes[0].id); //Here is where the code gives error.
  }, [dispatch]);

Make sure you check whether allMemes is already populated when you access it:

const allMemes = useSelector(selectAllJson);

console.log('memes: ', allMemes); // initially 'undefined' but eventually populated via your thunk

// When using memes, make sure it is populated
return allMemes ? allMemes.data.memes[0].id : 'Loading...';
about 4 years ago · Juan Pablo Isaza Report

0

I think this solution works, but the reason for the error is not the async type of your fetch request. The reason for this error is the current closure of your effect-function. Quoted by Eric Elliott:

"A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time."

See also this link: https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36

Depending on this, allMemes in the effect-function will be an empty object (like your initialization) also by dispatching an action-object and not a thunk.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!