I can’t update the data in useEffect, even after using async.
Note: I don’t to add data as dependency in useEffect as I want to fetch data only once
import { useEffect, useState } from "react"
function RenderBody() {
let [data, setData] = useState([])
useEffect(() => {
async function fetchData() {
let response = await fetch('https://dummyjson.com/products/1')
let responseJson = await response.json();
console.log(responseJson);
await setData((prevData) => {
return {...prevData, responseJson}
});
console.log(data);
}
fetchData();
}, []);
return (
<>
{data.length > 0 ? data.map(element => {
return <>
<div>{element.brand}</div>
<div>{element.price}</div>
</>
}) : <div>Nothing to display</div>}
</>
)
}
export default RenderBody ```
2
Answers
Sure you can, and you are. But what are you updating it to? The state value is initially an array:
And initially the UI doesn’t display anything because it checks the
length
property of the array:Then you update state to an object:
Since this object has no
length
property,data.length
isundefined
. Andundefined
is not> 0
, so the UI continues to successfully not display anything.Assuming
responseJson
is an object to be added to the array, it looks like you just want to spread into an array instead of an object:(Note also that I removed the
await
, since usingawait
on something that isn’t awaitable is a no-op, so the keyword isn’t doing anything useful there.)As an aside… Since this effect only occurs once when the component first loads, and it’s known that the state value is empty, you can do without the
prevData
approach entirely and simplify:Additionally… You can remove the
console.log(data);
on the line after updating state. This is just going to log an empty array to the console, and you already know the initial state was an empty array because it’s explicitly defined as such in the code.If you want to log the new state, that value is in
responseJson
, which you already logged.You setting the data to an object instead of an array.