#javascript #reactjs
#javascript #reactjs
Вопрос:
Я все еще пытаюсь разобраться в том, как react обрабатывает рендеринг, и это конкретное поведение заставило меня весь день ломать голову. Когда я запускаю этот код, я получаю 3 журнала консоли. Первое значение равно нулю, как и ожидалось, поскольку useEffect еще не был запущен. Затем я получаю выбранный массив worldData из моего вызова api, как и ожидалось. Однако затем я получаю третий консольный журнал с тем же указанным массивом, что наводит меня на мысль, что мой компонент повторно отображается. Если я добавлю другое установленное состояние и другой вызов api, я увижу еще один журнал консоли.
function App() {
const [worldData, setWorldData] = useState(null)
const [countriesData, setCountriesData] = useState(null)
useEffect(() => {
const fetchData = async () => {
const [world, countries] = await Promise.all([
fetch("https://disease.sh/v3/covid-19/countries?yesterday=true").then(res => res.json()),
fetch("https://disease.sh/v3/covid-19/all?yesterday=true").then(res => res.json())
])
.catch((err) => {
console.log(err)
})
setWorldData(world)
setCountriesData(countries)
}
fetchData();
}, []);
console.log(worldData);
Похоже, что react выполняет рендеринг каждый раз, когда я устанавливаю состояние, для чего, я полагаю, он и предназначен. Однако я читал в другом месте, что react объединяет несколько заданных состояний вместе, когда они устанавливаются вместе в useEffect. Итак, почему тогда мои заданные состояния не обрабатываются? Это из-за асинхронного кода? Если да, то есть ли способ, которым я могу получить несколько конечных точек и установить все полученные данные одновременно, чтобы моему компоненту нужно было выполнить повторный запуск только один раз?
Ответ №1:
Пара бит
(1) Если вас интересует ТОЛЬКО одно обновление состояния, вы можете определить одно состояние и обновить его как таковое
const [fetched_data, updateFetchedData] = useState({world:null, countries:null});
...
// where *world* and *countries* are variables containing your fetched data
updateFetchedData({world, countries})
...
fetched_data.world // using the fetched data somewhere
(2) ОДНАКО ваш код не должен заботиться о получении нескольких обновлений и должен обслуживать его как таковой…
Ваш useState должен определять, как будет выглядеть пустой результат, например, вместо
const [worldData, setWorldData] = useState(null); // probably shouldn't look like this
как насчет
const [worldData, setWorldData] = useState([]); // this is what an empty result set looks like
И внутри любого компонента, который использует данные как мира, так и стран (я предполагаю, что один ссылается на другой, поэтому вам нужны оба обновления одновременно), просто поместите условный оператор, который, если он не найден, затем поместите некоторую строку ‘Loading’ или ‘NA’ или что-то еще, пока оно не будет загружено.