Как работает lazy загрузка в useSWR
Что проверяют
Понимаете ли вы, что в SWR нет отдельного «ленивого» режима, а есть управление ключом. Интервьюер ждёт, как не отправить запрос раньше времени и как запустить загрузку по действию пользователя. Следом спрашивают про зависимые запросы или бесконечную ленту.
Как отвечать
- условная загрузка: если ключ равен
nullили функция-ключ вернулаnullлибо бросила исключение,useSWRзапрос не отправляет. Типичная записьuseSWR(shouldFetch ? '/api/profile' : null, fetcher), гдеshouldFetchстановитсяtrueпо клику или при открытии вкладки; - зависимые запросы: второй ключ строится из данных первого,
useSWR(() => '/api/projects?owner=' + user.id). Покаuserне загружен, обращение кuser.idбросает, и SWR просто ждёт; - по требованию:
useSWRMutationизswr/mutationсам не стартует, запрос уходит только при вызовеtrigger(). Задуман он для изменений, но подходит и для разовой загрузки по кнопке; - порциями:
useSWRInfiniteгрузит страницы, следующую запрашивают черезsetSize(size + 1), например изIntersectionObserverу конца списка. Сам SWR за прокруткой не следит; - заранее:
preload(key, fetcher)прогревает кэш, например при наведении на ссылку.
Рядом стоит сказать, что управляет повторными запросами: по умолчанию SWR перепроверяет данные при фокусе окна и восстановлении сети, а одинаковые ключи в течение dedupingInterval (2 секунды) схлопываются в один запрос. Для редко меняющихся данных есть useSWRImmutable.
Где спотыкаются
Показывают спиннер по условию !data. Когда ключ null, данных не будет никогда, и компонент крутит загрузку вечно. Во второй версии для этого есть isLoading, который при пустом ключе равен false.
Собирают ключ из неготового значения: '/api/users/' + id при id === undefined отправит запрос на /api/users/undefined. Обратная ошибка: проверка id ? ... : null не загрузит пользователя, у которого id равен 0.
Путают с React.lazy и разделением кода или берут пример из старой статьи с ключом-массивом, где элементы раскладывались по параметрам fetcher. Во второй версии fetcher получает ключ целиком одним аргументом: ([url, id]) => ....