> Как заставить useSWR отрабатывать только на клиенте, пропуская сервер (React, JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Библио-Глобус
Стек: React, JavaScript
> Пример ответа
Короткий ответ
Чтобы useSWR работал только на клиенте, нужно либо вынести его вызов в компонент, обёрнутый в динамический импорт с ssr: false, либо использовать флаг isFallback из Next.js, либо проверять typeof window === 'undefined' и вызывать хук только на клиенте. Самый надёжный способ - динамический импорт компонента с next/dynamic и отключением SSR.
Подробное объяснение
useSWR по умолчанию выполняется и на сервере, и на клиенте. Это может быть проблемой, если данные зависят от браузерных API (localStorage, window.location) или если серверный рендеринг нежелателен. Основные подходы:
-
Динамический импорт с
ssr: false- компонент с useSWR загружается только на клиенте, сервер его пропускает. Это чистое решение для Next.js. -
Проверка
typeof window- внутри компонента проверяем, что мы на клиенте, и только тогда вызываем useSWR. Минус - хук всё равно монтируется, но не делает запрос. -
Флаг
isFallback- в Next.js можно использоватьfallbackв getStaticProps, но это не отключает серверный вызов useSWR, а лишь подставляет начальные данные. -
Условный рендеринг с useEffect - можно вынести логику запроса в useEffect и не использовать useSWR напрямую, но это теряет преимущества библиотеки.
Лучший вариант для Next.js - динамический импорт, так как он гарантирует, что код useSWR не попадёт в серверный бандл.
На практике
В реальных проектах чаще всего используют next/dynamic для компонентов, которые зависят от клиентских данных. Например, виджет погоды, который берёт геолокацию из браузера, или форма с сохранением черновиков в localStorage. Также это актуально для компонентов, использующих IntersectionObserver или WebSocket.
Если проект не на Next.js, а на чистом React с SSR (например, через Express), можно использовать проверку typeof window или флаг isClient из стейт-менеджера.
Пример кода
JSX// components/ClientData.jsimport useSWR from 'swr'export default function ClientData() {const { data } = useSWR('/api/data', fetcher)return <div>{data?.message}</div>}// pages/index.jsimport dynamic from 'next/dynamic'const ClientData = dynamic(() => import('../components/ClientData'), {ssr: false,})export default function Home() {return (<div><h1>Главная</h1><ClientData /></div>)}
Альтернативный вариант с проверкой:
JSXfunction ClientData() {const isClient = typeof window !== 'undefined'const { data } = isClient ? useSWR('/api/data', fetcher) : { data: null }return <div>{data?.message}</div>}
Как отвечать на собеседовании
Начни с того, что useSWR по умолчанию работает и на сервере, и на клиенте. Затем перечисли основные способы, выделив динамический импорт как самый надёжный для Next.js. Объясни, почему это важно: избегаем ошибок из-за отсутствия браузерных API, уменьшаем серверную нагрузку, ускоряем TTFB. Упомяни trade-off: динамический импорт добавляет дополнительный сетевой запрос для загрузки чанка. Если спросят про SWR без Next.js, расскажи про проверку typeof window.
Что проверяет интервьюер
Интервьюер проверяет понимание различий между серверным и клиентским рендерингом, знание особенностей useSWR и Next.js, умение выбирать правильный инструмент для задачи. Также оценивается способность объяснить trade-off каждого подхода и аргументировать выбор.
Типичные ошибки
- Использование
useEffectдля вызова useSWR - это нарушает правила хуков и может привести к race conditions. - Забывают, что динамический импорт с
ssr: falseсоздаёт отдельный чанк, который загружается асинхронно - это может повлиять на UX. - Пытаются отключить серверный вызов через конфигурацию SWR (например,
revalidateOnMount: false) - это не решает проблему, хук всё равно выполняется на сервере. - Используют
typeof windowвнутри хука, но не учитывают, что на сервере useSWR всё равно монтируется и может вызвать ошибки в консоли.
> Похожие задачи по frontend
Является ли рендеринг в React блокирующей операцией для исполнения JavaScript кода
В чем разница Redux и React Context
Как обработать ошибки в React приложении
Как реализовать добавление и удаление кнопок с уникальными id в React при кликах
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью