Как вызвать useSWR по нажатию на кнопку, чтобы он не вызывался сразу
Что проверяют
Знаете ли вы, как SWR решает, делать ли запрос, и не полезете ли вызывать хук внутри обработчика клика. Следом обычно спрашивают, как повторить запрос по второму нажатию и чем здесь поможет useSWRMutation.
Как отвечать
Главная идея: SWR не отправляет запрос, если ключ равен null (или функция-ключ вернула null либо бросила ошибку). Поэтому хук вызывается всегда, на верхнем уровне компонента, а управляется ключом:
- условный ключ:
const [query, setQuery] = useState<string | null>(null), затемuseSWR(query ? ['/api/search', query] : null, fetcher). Кнопка кладёт значение в состояние, ключ становится непустым, и запрос уходит. В SWR 2 ключ-массив приходит вfetcherодним аргументом; - повтор: второй клик с тем же значением ключ не меняет, запроса не будет. Для явного обновления берут
mutate()из результата хука; useSWRMutationизswr/mutation: возвращаетtrigger, который вызывается вonClick, и при монтировании ничего не запрашивает. Это правильный выбор, если по кнопке уходит POST или действие с побочным эффектом. По умолчанию результатtriggerне пишется в общий кеш, за это отвечает опцияpopulateCache.
Отдельно скажите про автоматические перезапросы. Как только ключ стал непустым, SWR перезапрашивает данные при фокусе окна и восстановлении сети. Если нужен ровно один запрос по клику, отключите revalidateOnFocus и revalidateOnReconnect или используйте useSWRImmutable.
Состояния показывайте через isLoading и error: при ключе null isLoading равен false, и до клика не нужно рисовать «Загрузка».
Где спотыкаются
Вызывают useSWR внутри onClick. Хук вне рендера нарушает правила хуков, и React выбрасывает Invalid hook call.
Показывают индикатор загрузки по условию !data, и он висит на экране ещё до первого клика.
Удивляются, что «однократный» запрос повторяется при переключении вкладки: забыли, что после появления ключа работает ревалидация по фокусу.