Загрузка программы
Загрузка данных — тоже работа для эффекта. Приложение должно один раз попросить у сервера программу, когда появляется, поэтому у эффекта зависимости []. Группы лежат в файле bands.json, и вы загружаете их с помощью fetch(), как в курсе JavaScript:
useEffect(() => {
async function loadBands() {
const response = await fetch("bands.json");
setBands(await response.json());
}
loadBands();
}, []);Зачем функция внутри? Для fetch() нужен await, а await работает только в async-функции. Но функция, которую вы передаёте useEffect, сама не может быть async: async-функция всегда возвращает промис, а React ждёт от эффекта, что он ничего не вернёт или вернёт очистку. Поэтому эффект создаёт async-функцию и тут же вызывает её.
Первая отрисовка показывает пустой список, потому что bands сначала равно []. Через мгновение данные приходят, setBands() меняет состояние, и React отрисовывает список с группами. Эффект больше не запускается: его зависимости не изменились.
Пока пользователь ждёт, страница должна об этом сказать, а если сервер ответил ошибкой — сказать и об этом. И то и другое — ещё состояние: loading, которое равно true, пока не пришёл ответ, и error с текстом сообщения об ошибке или "", если ошибки нет. Страница показывает каждое из них с помощью &&:
{loading && <p>Загрузка…</p>}
{error !== "" && <p className="error">{error}</p>}И вспомните response.ok из курса JavaScript: оно равно false, когда сервер ответил ошибкой, например 404 Not Found для неверно написанного имени файла.
Типичная ошибка — вызвать fetch() прямо в компоненте, без эффекта. Тогда каждая отрисовка загружает данные заново, данные меняют состояние, новое состояние снова вызывает отрисовку… и приложение без конца обращается к серверу снова и снова.
Задание
- 1
Добавьте эффект с зависимостями
[], который загружаетbands.jsonи кладёт группы вbandsс помощьюsetBands(). Тогда список покажет все пять групп. - 2
Добавьте переменную состояния
loading, сначала равнуюtrue, и послеsetBands()задайте ейfalse. Пока она равнаtrue, показывайте<p>Загрузка…</p>над списком. - 3
Если ответ не OK, задайте
loadingзначениеfalse, поместитеНе удалось загрузить программу.в переменную состоянияerror(сначала"") и завершите функцию с помощьюreturn. Показывайте ошибку в<p className="error">над списком. Попробуйте: допустите опечатку в имени файла вfetch(), а потом исправьте её.