---
title: SSR и CSR
seo:
  title: SSR и CSR — React Developer
  description: Тема «SSR и CSR» для собеседования React Developer. Что такое SSR (Server-Side Rendering) и как он отличается от CSR (Client-Side Rendering)? Как передать данные с сервера на клиент при использовании SSR в React?
---

[Все темы React Developer](/react-developer)

## <strong>Что такое SSR (</strong><code>Server&#45;Side Rendering</code><strong>) и как он отличается от CSR (</strong><code>Client&#45;Side Rendering</code><strong>)?</strong> [#q-14bee738d69b817d9ef7d79191a04e36]

SSR (<code>Server&#45;Side Rendering</code>) и CSR (<code>Client&#45;Side Rendering</code>)&#58;

<strong>SSR (Server-Side Rendering)</strong>&#58;

- Рендеринг контента на сервере.

- HTML генерируется на сервере и отправляется в браузер.

- HTML с контентом доступен без ожидания клиентского рендера, что может ускорить показ страницы и упростить индексацию.

- Пример&#58; Next.js.

<strong>CSR (Client-Side Rendering)</strong>&#58;

- Рендеринг контента на клиенте.

- HTML генерируется в браузере с помощью JavaScript.

- Для первого показа контента обычно нужны загрузка и выполнение JavaScript. Степень интерактивности не определяется выбором CSR или SSR.

- Пример&#58; Create React App.

#### Основные отличия&#58;

{/* prettier-ignore */}
- <strong>Производительность</strong>&#58;

    - SSR может ускорить показ контента, но зависит от времени ответа сервера и объёма клиентского JavaScript.

    - CSR может задержать первый показ контента; скорость дальнейших переходов зависит от приложения и кеширования.

- <strong>SEO</strong>&#58;

    - SSR&#58; Улучшенная SEO, так как контент доступен поисковым системам.

    - CSR&#58; Хуже для SEO, так как контент рендерится динамически.

- <strong>Сложность</strong>&#58;

    - SSR&#58; Более сложная настройка и инфраструктура.

    - CSR&#58; Проще в настройке и развертывании.

:::note[Ссылки для изучения]

1. [Рендеринг приложений в React](https://habr.com/ru/companies/alfa/articles/725626/)
   :::

---

## <strong>Как передать данные с сервера на клиент при использовании</strong> <code>SSR</code> <strong>в React?</strong> [#q-14bee738d69b81e59534ee525ec2a49d]

В Next.js Pages Router серверные данные можно передать странице через getServerSideProps. getInitialProps является устаревшим API. В App Router используют серверные компоненты и передают клиентским компонентам сериализуемые пропсы. Секреты и служебные данные в клиентские пропсы не включают.

#### Пример с <code>getServerSideProps</code> в Next.js&#58;

1. <strong>Создайте страницу и реализуйте</strong>
   <code>getServerSideProps</code>&#58;

   ```jsx
   import React from "react";

   export async function getServerSideProps() {
     // Получение данных на сервере
     const res = await fetch("https://api.example.com/data");
     const data = await res.json();

     // Передача данных в компонент через пропсы
     return { props: { data } };
   }

   const Page = ({ data }) => (
     <div>
       <h1>Server-Side Rendered Page</h1>
       <pre>{JSON.stringify(data, null, 2)}</pre>
     </div>
   );

   export default Page;
   ```

#### Пример с <code>getInitialProps</code> в Next.js (для классовых компонентов или старых версий Next.js)&#58;

1. <strong>Создайте страницу и реализуйте</strong> <code>getInitialProps</code>
   &#58;

   ```jsx
   import React from "react";

   class Page extends React.Component {
     static async getInitialProps() {
       // Получение данных на сервере
       const res = await fetch("https://api.example.com/data");
       const data = await res.json();

       // Передача данных в компонент через пропсы
       return { data };
     }

     render() {
       const { data } = this.props;
       return (
         <div>
           <h1>Server-Side Rendered Page</h1>
           <pre>{JSON.stringify(data, null, 2)}</pre>
         </div>
       );
     }
   }

   export default Page;
   ```

getServerSideProps выполняется на сервере; getInitialProps при первой загрузке выполняется на сервере, а при клиентских переходах может выполняться в браузере. Оба относятся к Pages Router.

:::note[Ссылки для изучения]

1. [Рендеринг приложений в React](https://habr.com/ru/companies/alfa/articles/725626/)
   :::

---

## <strong>Что такое "реактивное программирование" (</strong><code>reactive programming</code><strong>) в контексте React?</strong> [#q-14bee738d69b81118f02fa5c90a4ef0e]

<strong>Реактивное программирование</strong> — это парадигма программирования,
ориентированная на асинхронные потоки данных и изменение состояния, где
реактивные системы автоматически обновляются в ответ на изменение данных.

#### В контексте React&#58;

{/* prettier-ignore */}
1. <strong>Компоненты обновляются автоматически</strong>&#58;

    - Компоненты React автоматически перерисовываются в ответ на изменение состояния или пропсов.

1. <strong>Использование хуков</strong>&#58;

    - Хуки, такие как <code>useState</code>, <code>useEffect</code>, и <code>useReducer</code>, позволяют управлять состоянием и побочными эффектами, обеспечивая реактивное поведение.

    ```javascript
    const [count, setCount] = useState(0);

    useEffect(() => {
      console.log(`Count has changed to ${count}`);
    }, [count]);
    ```

1. <strong>Интеграция с библиотеками</strong>&#58;

    - Библиотеки, такие как RxJS, могут быть использованы для управления асинхронными потоками данных в приложениях React.

    ```jsx
    import { useEffect } from 'react';
    import { fromEvent } from 'rxjs';

    const MyComponent = () => {
      useEffect(() => {
        const subscription = fromEvent(document, 'click').subscribe(() => {
          console.log('Document clicked');
        });

        return () => subscription.unsubscribe();
      }, []);

      return <div>Click anywhere in the document</div>;
    };
    ```

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

:::note[Ссылки для изучения]

1. [Рендеринг приложений в React](https://habr.com/ru/companies/alfa/articles/725626/)
   :::

---

## <strong>Как обновить состояние компонента после выполнения асинхронной операции?</strong> [#q-14bee738d69b8148873de003984ebf82]

Для обновления состояния компонента после выполнения асинхронной операции используйте <code>useState</code> и <code>useEffect</code> хуки в функциональных компонентах.

#### Шаги&#58;

1. <strong>Создайте состояние с помощью</strong> <code>useState</code>&#58;

   ```javascript
   const [data, setData] = useState(null);
   const [loading, setLoading] = useState(true);
   const [error, setError] = useState(null);
   ```

1. <strong>Выполните асинхронную операцию внутри</strong> <code>useEffect</code>
   &#58;

   ```javascript
   useEffect(() => {
     const fetchData = async () => {
       try {
         const response = await fetch("https://api.example.com/data");
         const result = await response.json();
         setData(result); // Обновление состояния с данными
         setLoading(false); // Установка состояния загрузки в false
       } catch (err) {
         setError(err); // Обновление состояния ошибки
         setLoading(false); // Установка состояния загрузки в false
       }
     };

     fetchData();
   }, []); // Пустой массив зависимостей, чтобы выполнить только при монтировании
   ```

#### Пример&#58;

```jsx
import React, { useState, useEffect } from "react";

const MyComponent = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch("https://api.example.com/data");
        const result = await response.json();
        setData(result); // Обновление состояния с данными
        setLoading(false); // Установка состояния загрузки в false
      } catch (err) {
        setError(err); // Обновление состояния ошибки
        setLoading(false); // Установка состояния загрузки в false
      }
    };

    fetchData();
  }, []);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return <div>{JSON.stringify(data)}</div>;
};

export default MyComponent;
```

Для обновления состояния компонента после выполнения асинхронной операции используйте хуки <code>useState</code> для хранения состояния и <code>useEffect</code> для выполнения асинхронного запроса и обновления состояния.

:::note[Ссылки для изучения]

1. [Рендеринг приложений в React](https://habr.com/ru/companies/alfa/articles/725626/)
   :::
