Рендеринг на стороне клиента (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 также можно использовать интерфейс загрузки с Suspense для отображения индикатора загрузки во время рендеринга страницы.