На почти 1 день встала разработка из-за того, что сразу не сообразил про особенность работы useState, хотя с ним не первый день работаю. Нужно было сформировать массив данных в React приложении через useState и axios, который тащил данные из API с разными параметрами. Посто про мои грабли и то, как не потратить 1 день на поиск не существующего бага React.
Если в React приложении нужно получить данные из нескольких однотипных запросов и поместить их в массив при загрузке через useState и useEffect, то не надо стараться это разбить на несколько загрузок, а надо загрузить их за один цикл функции.
Я использую axios для загрузки, а в нем есть метод all. Пока не переписал загрузку на его использование, то было так – один раз открываю страницу после компиляции и все ок, перегружаю – и данные не отображаются на странице. При этом, переменные имеют нужные значения. Это связано с асинхронностью работы useState, которым я пытался последовательно обновлять данные.
После реализации через axios.all (в принципе, можно через что угодно делать, только не пытаться обновлять данные через useState, а делать все внутри тела одной функции), все заработало.
Пример кода
const langs: string[] = ['ru', 'en', 'he', 'qq'] const defaultContent: Map<string, ISiteObjects> = new Map<string, ISiteObjects>() langs.forEach(element => { defaultContent.set(element, emptyObject) }) const [content, setContent] = useState<Map<string, ISiteObjects>>(defaultContent) const [isLoaded, setIsLoaded] = useState<boolean>(false) const mainUrl = 'https://localhost:5001/api/Lang/' const readdata = async (): Promise<void> => { const urls = langs.map(x => { return mainUrl + x }) const requests = urls.map(async (url) => await axios.get(url)) axios.all(requests).then(responses => { const data = new Map<string, ISiteObjects>() responses.forEach((res, i) => { if (data.has(langs[i])) data.delete(langs[i]) data.set(langs[i], res.data) }) setContent(data) }).catch(err => { console.log(err) }) } useEffect(() => { void readdata() setIsLoaded(true) }, [])