I have
const [items, setItems] = useState<any[]>(itemsB.map(() => ({ loading: true })));
and
itemsB.map(async (itemB: any, index: number) => {
searchItems(itemB).then(result => {
const newItems = [...items]; // Ref A
newItems[index] = result;
setItems(newItems);
})
})
Because the inner function is an async fetch, items come back in an unpredictable order, and I want to add them to items
as soon as they're ready, changing the placeholder loading object with the actual result. This almost does that, but the items
referenced at Ref A does not update, so it cycles through changing each thing and then at the end only the last item to have been retrieved appears.
If I do a Promise.all().then()
, it waits until all items are retrieved to execute the then
part, so I'm wondering how to set items as they are resolved.
The calls made to setItems are batched to optimize performance. If the previous state relies on the current state, use the overloaded version of setItems which takes the previousState as the first argument.
searchItems(itemB).then(result => {
setItems(items => {
const newItems = [...items]; // Ref A
newItems[index] = result;
return newItems;
});
})