Reputation: 3615
I'm using the useState hook to populate items in an array.
const [meals, setMeals] = useState([]);
useEffect(async () =>{
const mealsData = await fetchMeals(localStorage.getItem('user_id'));
console.log(mealsData);// Array(3)
setMeals([...meals, mealsData]);
console.log(meals);//[]
}, []);
The array doesn't get copies in my setMeals method, what am I doing wrong here?
Upvotes: 1
Views: 626
Reputation: 767
This is because
setMeals([...meals, mealsData]);
is an asynchronous call and you are logging the meals
before being sure the state actually updated
console.log(meals);
You should call and check your console.log()
function in another useEffect()
call which runs on every state change and assures that the state actually changed
useEffect(() => {
console.log(meals);
}, [meals]);
[meals]
passed as the second argument will let this useEffect()
run every time meals
(actually) update.
Upvotes: 3
Reputation: 2345
You are actually not doing anything wrong, state updates are not synchronous, so logging meals
immediately after updating it will not show the updated value
Use an effect for the meals
array to detect when it has actually changed...
useEffect(() => {
console.log(meals);
}, [meals]);
Upvotes: 0
Reputation: 142
UseEffect cannot be async you should wrap it in an async function
function useMeals() {
const [meals, setMeals] = useState([]);
useEffect(() => {
async function setFetchedMeals() {
const mealsData = await fetchMeals(localStorage.getItem('user_id'));
setMeals([...meals, mealsData]);
}
setFetchedMeals();
}, []); // letting the dependency array empty will run the effect only once
console.log(meals)
return meals;
}
Upvotes: 0
Reputation: 609
the update is asynchronous, the new value is not available immediately as you're expecting. You can find an in-depth explanation here: useState set method not reflecting change immediately
Upvotes: 0