---
title: Компоненты
seo:
  title: Компоненты — React Developer
  description: Тема «Компоненты» для собеседования React Developer. Какие основные различия между компонентами классов и функциональными компонентами в React? Как реализовать PureComponent?
---

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

## <strong>Какие основные различия между компонентами классов и функциональными компонентами в React?</strong> [#q-14bee738d69b8141b935cd5bd90adf12]

В React существуют два основных способа создания компонентов&#58; с использованием классов и с использованием функциональных компонентов. Вот основные различия между ними&#58;

<strong>Компоненты классов&#58;</strong>

1. <strong>Синтаксис&#58;</strong> Компоненты классов определяются как классы,
   расширяющие базовый класс <code>React&#46;Component</code>.

1. <strong>Состояние (state)&#58;</strong> Компоненты классов имеют встроенную
   поддержку для состояния (state), что позволяет им хранить и управлять данными
   внутри компонента.

1. <strong>Методы жизненного цикла&#58;</strong> Компоненты классов обладают
   широким набором методов жизненного цикла (например, 
   <code>componentDidMount</code>, <code>componentDidUpdate</code>, 
   <code>componentWillUnmount</code>), которые позволяют реагировать на
   различные этапы жизни компонента.

1. <strong>Пропсы (props)&#58;</strong> Пропсы передаются в компоненты классов
   через атрибуты при использовании. Они доступны через 
   <code>this&#46;props</code> внутри методов компонента.

<strong>Функциональные компоненты&#58;</strong>

1. <strong>Синтаксис&#58;</strong> Функциональные компоненты определяются как
   обычные функции.

1. <strong>Состояние (state)&#58;</strong> Изначально функциональные компоненты
   не поддерживали состояние. Однако с появлением хуков (hooks) в React (начиная
   с React 16.8) функциональные компоненты теперь могут использовать состояние и
   другие возможности, которые ранее были доступны только компонентам классов.

1. <strong>Хуки (hooks)&#58;</strong> Функциональные компоненты могут
   использовать хуки, такие как <code>useState</code>, <code>useEffect</code> и
   другие, для управления состоянием, эффектами и другими аспектами.

1. <strong>Пропсы (props)&#58;</strong> Пропсы также передаются функциональным
   компонентам, но доступны они как аргументы функции.

В целом, с появлением хуков, функциональные компоненты стали предпочтительным выбором для большинства случаев в React, так как они обеспечивают более простой и читаемый синтаксис, а также упрощенный способ управления состоянием и эффектами.

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

1. [Your first component on React](https://react.dev/learn/your-first-component)
   :::

---

## <strong>Как реализовать</strong> <code>PureComponent</code><strong>?</strong> [#q-14bee738d69b819d82b2e1e43929a9d5]

PureComponent используется для классовых компонентов. Для функциональных компонентов похожую оптимизацию по пропсам предоставляет memo, который не является хуком.

<strong>С использованием классов&#58;</strong>

```jsx
import React, { PureComponent } from "react";

class MyPureComponent extends PureComponent {
  render() {
    return <div>{/* Ваш код компонента */}</div>;
  }
}

export default MyPureComponent;
```

Для функционального компонента с memo&#58;

```jsx
import React, { memo } from "react";

const MyPureComponent = () => {
  return <div>{/* Ваш код компонента */}</div>;
};

export default memo(MyPureComponent);
```

PureComponent поверхностно сравнивает новые и прежние props и state. memo по умолчанию сравнивает каждый проп через Object.is; собственное состояние и используемый контекст по-прежнему могут вызвать рендер. Это оптимизации, а не гарантия отсутствия повторного рендера.

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

1. [Your first component on React](https://react.dev/learn/your-first-component)
   :::

---

## <strong>Что такое</strong> <code>HOC</code> <strong>(Higher-Order Component) в React?</strong> [#q-14bee738d69b819eb707e91c96f8a16b]

Высокоуровневый компонент (Higher-Order Component, HOC) - это паттерн в React, который позволяет повторно использовать логику компонентов, абстрагируя ее от самих компонентов. HOC не является частью API React, это скорее паттерн композиции компонентов.

<code>HOC</code> - это функция, которая принимает компонент и возвращает новый
компонент с дополнительной логикой. HOC позволяют вынести общие функциональные
или структурные аспекты компонентов и повторно использовать их с разными
компонентами.

Пример <code>HOC</code>&#58;

```jsx
import React from "react";

const withLogger = (WrappedComponent) => {
  return class WithLogger extends React.Component {
    componentDidMount() {
      console.log("Компонент был отрисован");
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
};

const MyComponent = () => {
  return <div>Содержимое компонента</div>;
};

const EnhancedComponent = withLogger(MyComponent);

export default EnhancedComponent;
```

В этом примере <code>withLogger</code> - это HOC, который добавляет логирование в метод <code>componentDidMount</code>. Затем компонент <code>MyComponent</code> обертывается HOC, создавая <code>EnhancedComponent</code>.

<code>HOC</code> позволяют&#58;

- Расширять функциональность компонентов без изменения самих компонентов.

- Переиспользовать код и логику между разными компонентами.

- Создавать общие паттерны для логирования, аутентификации, обработки ошибок и других аспектов.

Однако, с развитием React и появлением хуков, часть функциональности HOC теперь может быть реализована с использованием хуков, таких как <code>useEffect</code>, <code>useContext</code> и других. В большинстве случаев, использование хуков более предпочтительно.

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

1. [Your first component on React](https://react.dev/learn/your-first-component)
   :::

---

## <strong>В чем разница между</strong> <code>HOC</code> <strong>и компонентами рендер-пропсов (</strong><code>render props</code><strong>)?</strong> [#q-14bee738d69b8183a527c0b65ea4f5b5]

Как <code>HOC</code> (Высокоуровневый компонент, Higher-Order Component), так и компоненты с рендер-пропсами представляют паттерны в React для повторного использования логики между компонентами. Однако, у них есть различия в том, как они реализованы и как они используются.

<code>HOC</code> <strong>(Higher-Order Component)&#58;</strong>

1. HOC - это функция, которая принимает компонент и возвращает новый компонент с дополнительной логикой.

1. HOC можно использовать как обертку для компонентов, добавляя к ним общую функциональность.

1. HOC выполняются во время создания компонента, и логика, добавленная HOC, применяется при каждом рендере.

1. В HOC есть доступ к жизненным циклам компонента и его состоянию.

1. Пример HOC - <code>connect</code> из библиотеки Redux, который связывает компоненты с хранилищем состояния.

<strong>Компоненты с рендер-пропсами (Render Props Components)&#58;</strong>

1. Компонент с рендер-пропсами - это компонент, который принимает функцию в качестве свойства и вызывает эту функцию для рендеринга чего-либо.

1. Компонент с рендер-пропсами позволяет передавать логику рендеринга непосредственно в компонент, который использует этот компонент с рендер-пропсами.

1. Логика рендеринга передается через функцию-пропс и может быть использована при необходимости.

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

1. Пример компонента с рендер-пропсами - компоненты <code>Mouse</code> или <code>Toggle</code> в документации React.

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

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

1. [Your first component on React](https://react.dev/learn/your-first-component)
   :::

---

## <strong>Что такое фрагменты (</strong><code>fragments</code><strong>) в React?</strong> [#q-14bee738d69b81bbbf8cf11efd0eab7c]

Фрагменты (<code>fragments</code>) - это механизм в React, который позволяет вам группировать дочерние элементы без необходимости создавать лишние DOM-элементы. Они позволяют вернуть несколько элементов из компонента без оборачивания их в дополнительный DOM-контейнер.

До появления фрагментов, если вы хотели вернуть несколько элементов из компонента, вам приходилось обертывать их в дополнительный элемент (например, <code>&#60;div&#62;</code>) или использовать массив, что могло привести к лишнему уровню вложенности или проблемам с CSS.

С использованием фрагментов, это выглядит более чисто и эффективно&#58;

```jsx
import React from "react";

const MyComponent = () => {
  return (
    <>
      <h1>Заголовок</h1>
      <p>Параграф 1</p>
      <p>Параграф 2</p>
    </>
  );
};

export default MyComponent;
```

Фрагменты могут быть объявлены с помощью пустых <code>&#60;&#62;</code> и <code>&#60;&#47;&#62;</code>, а внутри них вы можете размещать любое количество дочерних элементов.

Фрагменты особенно полезны, когда вам нужно вернуть несколько элементов из компонента, например, из условных блоков или маппинга массивов, и вы хотите избежать создания дополнительных контейнеров в DOM.

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

1. [Your first component on React](https://react.dev/learn/your-first-component)
   :::

---

## <strong>Как организовать переиспользование компонентов в React?</strong> [#q-14bee738d69b81cfb2faf30c5889a63a]

Переиспользование компонентов - один из основных принципов разработки в React. Это позволяет создавать эффективный и легко поддерживаемый код. Вот некоторые методы организации переиспользования компонентов&#58;

1. <strong>Компоненты высшего порядка (HOC)&#58;</strong> Создание компонентов
   высшего порядка позволяет оборачивать другие компоненты, добавляя им
   определенное поведение. Это полезно для изоляции логики, которую вы хотите
   применить к нескольким компонентам.

1. <strong>Композиция компонентов&#58;</strong> Строить более сложные компоненты
   путем комбинирования более простых. Компоненты, которые представляют более
   общие элементы (например, кнопки, карточки и т.д.), могут быть повторно
   использованы и настроены в зависимости от конкретных потребностей.

1. <strong>Render Props&#58;</strong> Создание компонентов, которые передают
   функцию через свойство <code>children</code> или другое определенное
   свойство. Это позволяет другим компонентам использовать эту функцию для
   внедрения своего контента.

1. <strong>Хуки (Hooks)&#58;</strong> С React 16.8, хуки позволили
   переиспользовать состояние и логику в функциональных компонентах без
   использования классов. Вам даже можно создавать собственные пользовательские
   хуки для изоляции определенной функциональности.

1. <strong>Библиотеки компонентов&#58;</strong> Существует множество библиотек
   компонентов, таких как Material-UI, Ant Design, Chakra UI и другие,
   предоставляющие готовые компоненты для переиспользования в ваших проектах.

1. <strong>
     Компоненты страниц (Page Components) и компоненты макета (Layout
     Components)&#58;
   </strong>
    Разделение компонентов на те, которые отвечают за макет (навигация, боковая
   панель и т.д.) и те, которые отвечают за конкретное содержание страницы,
   может существенно повысить переиспользование.

1. <strong>
     Контейнеры и компоненты представления (Containers and Presentational
     Components)&#58;
   </strong>
    Разделяйте компоненты на "умные" контейнеры, которые управляют состоянием и
   бизнес-логикой, и "глупые" компоненты представления, которые отображают
   данные, переданные им из контейнеров.

Следуя этим методам, вы сможете организовать эффективное переиспользование компонентов в вашем приложении, что упростит поддержку кода и ускорит разработку.

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

1. [Your first component on React](https://react.dev/learn/your-first-component)
   :::

---

## <strong>Что такое "управляемые компоненты" (</strong><code>controlled components</code><strong>)?</strong> [#q-14bee738d69b81e3a6f2e0be648006bd]

"Управляемые компоненты" (<code>controlled components</code>) - это понятие, связанное с управлением состоянием форм и ввода данных в React. В управляемых компонентах значение элемента ввода (например, текстового поля или чекбокса) контролируется состоянием React компонента, а не DOM элементом.

Когда компонент контролирует значение ввода, он хранит это значение в своем состоянии и обновляет его с помощью обработчиков событий (например, при изменении текста в поле ввода). Это позволяет иметь полный контроль над данными формы и легко реагировать на изменения.

Пример управляемого компонента с текстовым полем&#58;

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

const ControlledComponent = () => {
  const [inputValue, setInputValue] = useState("");

  const handleInputChange = (event) => {
    setInputValue(event.target.value);
  };

  return (
    <div>
      <input type="text" value={inputValue} onChange={handleInputChange} />
      <p>Введенное значение: {inputValue}</p>
    </div>
  );
};

export default ControlledComponent;
```

В этом примере значение текстового поля <code>inputValue</code> связано со состоянием компонента. Когда значение текстового поля меняется, вызывается обработчик <code>handleInputChange</code>, который обновляет состояние и, следовательно, значение текстового поля.

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

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

1. [Your first component on React](https://react.dev/learn/your-first-component)
   :::

---

## <strong>Что такое "неуправляемые компоненты" (</strong><code>uncontrolled components</code><strong>)?</strong> [#q-14bee738d69b81a689ffd64b7294bed7]

"Неуправляемые компоненты" (<code>uncontrolled components</code>) - это понятие, противоположное управляемым компонентам, и оно относится к управлению состоянием форм и ввода данных в React. В случае неуправляемых компонентов, значение элемента ввода (например, input или textarea) хранится непосредственно в DOM, и React компонент не управляет этим значением.

Вместо использования состояния компонента для хранения значения элемента ввода, неуправляемые компоненты обращаются к DOM напрямую для получения и обновления значения.

Пример неуправляемого компонента с текстовым полем&#58;

```jsx
import React, { useRef } from "react";

const UncontrolledComponent = () => {
  const inputRef = useRef(null);

  const handleButtonClick = () => {
    alert("Значение в поле ввода: " + inputRef.current.value);
  };

  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={handleButtonClick}>Показать значение</button>
    </div>
  );
};

export default UncontrolledComponent;
```

В этом примере значение текстового поля не хранится в состоянии компонента. Вместо этого мы используем <code>useRef</code> для получения ссылки на DOM-элемент и затем получаем его значение через <code>inputRef&#46;current&#46;value</code>.

Неуправляемые компоненты могут быть полезны, когда у вас есть особые случаи или требования, где контроль над состоянием через React не является оптимальным подходом. Однако, в большинстве случаев, управляемые компоненты обеспечивают более предсказуемое и удобное управление данными в формах.

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

1. [Your first component on React](https://react.dev/learn/your-first-component)
   :::
