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

262
Visualizações
Applying State to Nested Object in React. How do I call API and display with Use Effect

So I have been re-iterating my code and working around with it for a few hours and I need help. My goal was to use useEffect to load an API call from a horoscope API. I ran into this error where I was only able to see the data AFTER I loaded another page from the website and re-rendered the homepage. My goal was to see the data displayed initially on useEffect() from when I called it. However, it seems to not work. Not sure if I need to use setInitialState, or manipulate the way I am exporting the values through context.

On further speculation, I somewhat see what the problem is in my code, but I have no idea HOW to use setInitialState to load values in from the api.

          initialState.data.yesterday = data;

Do I save this to the a variable then call set data on that variable?

1.) I tried manipulating state best I could could.

2.) Page never loads data from API on first run, only shows data after I click a button

3.) Code seems to need setInitialDate but can't find reasonable solution mixed with useEffect to get the data right.

Thank you!!

I am willing to hear all optimal solutions for my problem. I am not even sure if I am going in the right direction. Thanks.


const [initialState, setInitialState] = useState({
    data: {
        yesterday: {},
        today: {},
        tomorrow: {},
    }
});

useEffect(() => {
    console.log("useEffect called");
    // eslint-disable-next-line react-hooks/exhaustive-deps
    async function getDayInfos() {
        try {
            const response = await axios.post('https://aztro.sameerkumar.website/?sign=aries&day=yesterday');
            const data = response.data
            initialState.data.yesterday = data;
        } catch (error) {
            console.error(error);
        }


        try {
            const response = await axios.post('https://aztro.sameerkumar.website/?sign=aries&day=today');
            initialState.data.today = response.data
        } catch (error) {
            console.error(error);
        }

        try {
            const response = await axios.post('https://aztro.sameerkumar.website/?sign=aries&day=tomorrow');
            initialState.data.tomorrow = response.data
        } catch (error) {
            console.error(error);
        }
    }

    getDayInfos()
    // eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

return <AstroContext.Provider value={{initialState}}>
    {children}
</AstroContext.Provider>

}

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

React needs you to call the setter (e.g. setInitialState) in order to know that you've changed something that might require a re-render.

I understand it's tempting to try and do object manipulations when you have nested fields in your state, but given that your fields are changing basically all-at-once, we can do it atomically and improve your time-to-first-meaningful-data.

As an aside, I think initialState might not be a good idea for the name of your variable. Let's call it dayInfo because that's what it is. We also need to represent the state of the app while the data is being loaded - you'll be able to show a loading UI, you can get rid of that empty useEffect() dependency-array (and the ESLint disable comment) and it also really helps debugging.

Without any further ado, here's a working version:

// Document the shape of our state:
const initialState = {
  yesterday: {},
  today: {},
  tomorrow: {}
};

// Helper function that just gets a single day (to avoid repetition)
const fetchDay = async (day) => {
  try {
    const response = await axios.post(
      `https://aztro.sameerkumar.website/?sign=aries&day=${day}`
    );
    return response.data;
  } catch (error) {
    console.error(error);
  }
};

export default function App() {
  const [loadingState, setLoadingState] = useState("NOT_LOADED");
  const [dayInfo, setDayInfo] = useState(initialState);

  useEffect(() => {
    // Only go fetch the data if we haven't tried to yet
    if (loadingState === "NOT_LOADED") {
      setLoadingState("IN_PROGRESS");
      getDayInfos();
    }
  }, [loadingState]);

  async function getDayInfos() {
    // Fire off the three requests concurrently ...
    const yesterdayPromise = fetchDay("yesterday");
    const todayPromise = fetchDay("today");
    const tomorrowPromise = fetchDay("tomorrow");

    // ... but wait for them all to resolve here
    const [yesterday, today, tomorrow] = await Promise.all([
      yesterdayPromise,
      todayPromise,
      tomorrowPromise
    ]);

    setDayInfo({ yesterday, today, tomorrow });
    setLoadingState("LOADED");
  }

  ...
}

We've now clarified exactly when we're going to go and fetch the data.

We are also using Promises more effectively, firing off the three Axios fetches concurrently, rather than one-by-one. Finally, we atomically set the state of dayInfo and also indicate that we've got the data, to avoid fetching it ever again - much safer than an empty dependency array.

about 4 years ago · Juan Pablo Isaza Relatório

0

To @millhouse answer, I just add that it's always a good idea in React, or Redux, to keep your data as flatter as possible, since you need to make all immutable operations on your data to trigger the re-renders, and if you are not careful enough and have deep nested objects, you might find to have new objects with old referenced nested objects that cause all sort of subtle behaviours. If you are forced to use deep nested data structures, try Immer which is a great library that lets you to mutate an object deep nested property directly with the same result of a fully immutable operation.

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