Я работаю с приложением React и столкнулся со странной проблемой, причину которой знаю, но не могу найти способ ее исправить. У меня есть массив объектов, хранящихся в переменной. Теперь мне нужно сделать вызов API для каждого объекта в этом массиве и обновить в нем определенное поле, когда я получу ответ от вызова, а затем установить состояние компонента React.
Вызов API получает один объект за раз в качестве параметра, поэтому мне нужно сделать несколько вызовов API одновременно для каждого объекта в массиве состояний. Итак, множество вызовов API и множество вызовов функций установки состояния.
Настоящая кодовая база довольно сложна, поэтому я реконструировал ее базовую версию здесь. Вызов API просто добавит свойство email
к существующему объекту, а затем обновит локальное состояние. Я смоделировал вызов API, используя setTimeout
, и функция вызова API срабатывает при монтировании компонента. Когда цикл завершится и все вызовы setState
будут выполнены, в моем браузере появится только последний объект в переменной состояния, а не все объекты.
Поэтому я ожидаю ответа вида
[
{
id: 1,
name: 'Adam',
email: 'adam@gmail.com'
},
{
id: 2,
name: 'Michael',
email: 'michael@gmail.com'
},
{
id: 3,
name: 'Joseph',
email: 'joseph@gmail.com'
},
{
id: 4,
name: 'Noah',
email: 'noah@gmail.com'
}
]
Но вместо этого я получаю
[
{
id: 4,
name: 'Noah',
email: 'noah@gmail.com'
}
]
Я предполагаю, что это из-за асинхронного характера функции установки переменной состояния React. Таким образом, все последовательные вызовы установки состояния используют начальное состояние, потому что предыдущие вызовы еще не обновили состояние.
Итак, вот проблема, мне нужно сделать вызовы API для всех записей в массиве сразу, и как только я получу ответ, мне нужно обновить состояние. В некоторых ответах, которые я видел здесь, говорится об использовании Promise.all, но я считаю, что это будет ждать, пока все вызовы API не будут разрешены, но это повлияет на производительность моего приложения. Здесь также нельзя использовать useEffect, потому что я не хочу ждать завершения одного вызова API, а затем вызывать следующий. Но, может быть, я неправильно понимаю useEffect?
Я сам не могу придумать никакого решения, поэтому я был бы очень признателен за вашу помощь в поиске другого способа решения этой проблемы.
Можете ли вы делать вызовы API и обновлять состояние только после завершения всех вызовов?
Пожалуйста, включите в свой вопрос минимальный воспроизводимый пример (не только на JSFiddle).
@CVerica К сожалению, я не могу :( Не могу дождаться, пока все вызовы API вернут данные, так как со временем массив будет расти намного больше, и это действительно повлияет на производительность приложения с точки зрения того, как его воспринимают пользователи.