Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

97
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda