Рендеринг на стороне клиента (CSR)

При рендеринге на стороне клиента (CSR) с использованием React браузер загружает минимальную HTML-страницу и JavaScript, необходимый для работы страницы. Затем JavaScript используется для обновления DOM и отрисовки страницы. При первой загрузке приложения пользователь может заметить небольшую задержку перед тем, как увидит полную страницу, поскольку страница полностью рендерится только после загрузки, парсинга и выполнения всего JavaScript.

После первой загрузки страницы переходы между другими страницами того же сайта обычно происходят быстрее, так как загружаются только необходимые данные, а JavaScript может перерисовывать части страницы без полного её обновления.

В Next.js есть два способа реализации рендеринга на стороне клиента:

  1. Использование хука useEffect() React в ваших страницах вместо методов серверного рендеринга (getStaticProps и getServerSideProps).
  2. Использование библиотек для получения данных, таких как SWR или TanStack Query (рекомендуется).

Вот пример использования useEffect() на странице Next.js:

pages/index.js
import React, { useState, useEffect } from 'react'

export function Page() {
  const [data, setData] = useState(null)

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch('https://api.example.com/data')
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }
      const result = await response.json()
      setData(result)
    }

    fetchData().catch((e) => {
      // обработка ошибки при необходимости
      console.error('An error occurred while fetching the data: ', e)
    })
  }, [])

  return <p>{data ? `Your data: ${data}` : 'Loading...'}</p>
}

В примере выше компонент сначала рендерит Loading.... После получения данных он перерисовывается и отображает данные.

Хотя получение данных в useEffect — это паттерн, который можно встретить в старых приложениях React, мы рекомендуем использовать библиотеки для получения данных для лучшей производительности, кэширования, оптимистичных обновлений и других возможностей. Вот минимальный пример использования SWR для получения данных на клиенте:

pages/index.js
import useSWR from 'swr'

export function Page() {
  const { data, error, isLoading } = useSWR(
    'https://api.example.com/data',
    fetcher
  )

  if (error) return <p>Failed to load.</p>
  if (isLoading) return <p>Loading...</p>

  return <p>Your Data: {data}</p>
}

Полезно знать:

Учитывайте, что CSR может влиять на SEO. Некоторые поисковые роботы могут не выполнять JavaScript и видеть только начальное пустое состояние или состояние загрузки вашего приложения. Это также может привести к проблемам с производительностью у пользователей с медленным интернетом или устройствами, так как им придётся ждать загрузки и выполнения всего JavaScript перед отображением страницы. Next.js предлагает гибридный подход, позволяющий использовать комбинацию рендеринга на стороне сервера (SSR), статической генерации сайта (SSG) и рендеринга на стороне клиента в зависимости от потребностей каждой страницы вашего приложения. В App Router вы также можете использовать загрузочный UI с Suspense для отображения индикатора загрузки во время рендеринга страницы.