I have a simple functional component, which includes a fetch to a JSON file stored locally.
I am trying to bring in the data from the JSON file, and whilst this should be a simple task, I have come across a problem.
My console log is showing two separate logs - one is an empty object, presumably from the useState
definition and the second has the data from the fetch inside it.
Therefore, When I try to do anything with the data I'm fetching, undefined
is being returned, So I can't use it. I feel like I'm missing something obvious, but I'm not entirely sure what is going on here. I have tried async/await
without success.
What am I missing ?
const Landing = () => {
const [api, updateApi] = useState({});
const getData = () => {
fetch('data.json')
.then((response) => response.json())
.then((data) => updateApi({api: {data}}))
}
useEffect(() => {
getData();
}, []);
console.log(api)
return (
<p>Hey!</p>
)
}
CodePudding user response:
All you need to do is to wrap the return within an if/else block, and return (for example a spinning circle) loading indicator. When it re-renders with the data from the api, it returns the desired representation of the data.
CodePudding user response:
Using async/await syntax you can put your fetch
requests within the useEffect
hook and set your state similar to how you are currently doing.
export default function Landing() {
const [api, updateApi] = useState({});
useEffect(() => {
const getData = async () => {
const response = await fetch("data.json");
const data = await response.json();
updateApi({ api: { data } });
};
getData();
}, []);
return <div>{JSON.stringify(api)}</div>;
}
If you initialise the state with useState({})
then the value won't be undefined
. If however you want to check for that before doing something then an if/else statement as suggested in another answer is suitable or if it is within the component return
then a common pattern is return <div>{api && JSON.stringify(api)}</div>;
.
CodePudding user response:
Maybe you`re missing the fetch return:
const Landing = () => {
const [api, updateApi] = useState({});
const getData = () => {
fetch('data.json')
/* return the json */
.then((response) => return response.json())
.then((data) => updateApi({api: {data}}))
}
useEffect(() => {
getData();
}, []);
console.log(api)
return (
<p>Hey!</p>
)
}