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
In the first render,
LCS_Datahas the value you provided in youruseState({}).useEffectonly runs after your render, so when we reach yourconsole.log, accessing.LCS.infofrom{}gives an error. Only after a rerender triggered bysetLCSData(data)when thefetchcall returns willLCS_Databe the value returned from the API. So in this scenario, you can either:Pass a default value like
{ LCS: { info: 'default info' } }to useState so that before theuseEffectruns and thefetchcall returns, you have a value forLCS_Data.LCS.infoto be printed out.Use optional chaining (
LCS_Data.LCS?.info) to print outundefinedif there is no value yet.Note that this is how it should work: you will not have the value from the server until the
useEffectfires and thefetchcall returns. What you should do is to provide a default value before this happens.