> Как заставить useSWR отрабатывать только на клиенте, пропуская сервер (React, JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Библио-Глобус

Стек: React, JavaScript

> Пример ответа

Короткий ответ

Чтобы useSWR работал только на клиенте, нужно либо вынести его вызов в компонент, обёрнутый в динамический импорт с ssr: false, либо использовать флаг isFallback из Next.js, либо проверять typeof window === 'undefined' и вызывать хук только на клиенте. Самый надёжный способ - динамический импорт компонента с next/dynamic и отключением SSR.

Подробное объяснение

useSWR по умолчанию выполняется и на сервере, и на клиенте. Это может быть проблемой, если данные зависят от браузерных API (localStorage, window.location) или если серверный рендеринг нежелателен. Основные подходы:

  1. Динамический импорт с ssr: false - компонент с useSWR загружается только на клиенте, сервер его пропускает. Это чистое решение для Next.js.

  2. Проверка typeof window - внутри компонента проверяем, что мы на клиенте, и только тогда вызываем useSWR. Минус - хук всё равно монтируется, но не делает запрос.

  3. Флаг isFallback - в Next.js можно использовать fallback в getStaticProps, но это не отключает серверный вызов useSWR, а лишь подставляет начальные данные.

  4. Условный рендеринг с useEffect - можно вынести логику запроса в useEffect и не использовать useSWR напрямую, но это теряет преимущества библиотеки.

Лучший вариант для Next.js - динамический импорт, так как он гарантирует, что код useSWR не попадёт в серверный бандл.

На практике

В реальных проектах чаще всего используют next/dynamic для компонентов, которые зависят от клиентских данных. Например, виджет погоды, который берёт геолокацию из браузера, или форма с сохранением черновиков в localStorage. Также это актуально для компонентов, использующих IntersectionObserver или WebSocket.

Если проект не на Next.js, а на чистом React с SSR (например, через Express), можно использовать проверку typeof window или флаг isClient из стейт-менеджера.

Пример кода

JSX
// components/ClientData.js
import useSWR from 'swr'
export default function ClientData() {
const { data } = useSWR('/api/data', fetcher)
return <div>{data?.message}</div>
}
// pages/index.js
import dynamic from 'next/dynamic'
const ClientData = dynamic(() => import('../components/ClientData'), {
ssr: false,
})
export default function Home() {
return (
<div>
<h1>Главная</h1>
<ClientData />
</div>
)
}

Альтернативный вариант с проверкой:

JSX
function 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 всё равно монтируется и может вызвать ошибки в консоли.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью