Amir Adel
Amir Adel

Reputation: 33

React - Cannot access fetched data outside useEffect hook

I am trying to fetch data from a NodeJS server I created in React using the useEffect hook and the fetch API. the problem is I cannot access this data outside the useEffect callbacks This is my code:

import React, { useEffect, useState } from "react";

const App = () => {
  const [LCS_Data, setLCSData] = useState({});

  useEffect(() => {
    fetch("http://localhost:5000/lcs")
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        console.log(data);
        console.log(data.LCS.info);
        setLCSData(data);
      });
  }, []);

  // console.log(LCS_Data.LCS.info);

  return <div className="main"></div>;
};

export default App;

and this the output of the two console.logs in the useEffect: output of first console.log in the broswer

So everything is working fine, the data is structured as it should be and it is not corrupted in any way

that is until I uncomment the console.log before the return statement

it throws of this error

TypeError: Cannot read properties of undefined (reading 'info')

pointing at the last console.log when clearly the data is there.

How can I access properties inside my data object outside the scope of the useEffect hook so I can normally use it in my app

Upvotes: 0

Views: 901

Answers (1)

wai
wai

Reputation: 56

In the first render, LCS_Data has the value you provided in your useState ({}). useEffect only runs after your render, so when we reach your console.log, accessing .LCS.info from {} gives an error. Only after a rerender triggered by setLCSData(data) when the fetch call returns will LCS_Data be the value returned from the API. So in this scenario, you can either:

  1. Pass a default value like { LCS: { info: 'default info' } } to useState so that before the useEffect runs and the fetch call returns, you have a value for LCS_Data.LCS.info to be printed out.

  2. Use optional chaining (LCS_Data.LCS?.info) to print out undefined if there is no value yet.

Note that this is how it should work: you will not have the value from the server until the useEffect fires and the fetch call returns. What you should do is to provide a default value before this happens.

Upvotes: 1

Related Questions