Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

105
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda