Олег Марков
Что такое компоненты в React и как их применять
Введение
React — это популярная библиотека для создания пользовательских интерфейсов, основанных на компонентном подходе. Компоненты лежат в основе всей архитектуры React: это строительные блоки интерфейса, которые представляют отдельные элементы приложения. Компонент в React — это независимая, переиспользуемая часть UI, которую можно объединять с другими компонентами для создания сложных интерфейсов. Давайте подробно разберём, что такое компоненты в React, какие бывают их типы и как их эффективно применять в своих проектах.
Что такое компонент в React
Компонент в React — это функция или класс, которые принимают входные данные (props) и возвращают элементы React, описывающие, как должна выглядеть часть интерфейса. Каждый компонент инкапсулирует свою логику, разметку, стили и поведение.
Смотрите, если вам нужно показать кнопку, список или сложный виджет — для всего этого вы можете создать отдельные компоненты.
Внутри каждого React-приложения лежат компоненты. Понимание их структуры, жизненного цикла и способов взаимодействия — это фундамент разработки на React. Компонентный подход позволяет создавать переиспользуемый, модульный код, что значительно упрощает разработку и поддержку больших приложений. Правильная организация компонентов — это залог масштабируемости и поддерживаемости проекта. Если вы хотите детальнее погрузиться в основы работы с React и научиться создавать сложные интерфейсы из простых компонентов — приходите на наш большой курс Основы React, React Router и Redux Toolkit. На курсе 177 уроков и 17 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.
Преимущества компонентного подхода
- Переиспользуемость — один и тот же компонент можно использовать в разных частях приложения.
- Лёгкая поддержка — изменения в одном компоненте изолированы и не влияют на остальные части приложения напрямую.
- Простота тестирования — каждый компонент можно протестировать отдельно.
- Декомпозиция — большие задачи можно разбивать на небольшие, управляемые части.
Классификация компонентов
React выделяет два основных типа компонентов: Функциональные и Классовые. Давайте рассмотрим разницу между ними.
Функциональные компоненты
Это простейший способ создания компонента. Сейчас функциональные компоненты — стандарт в разработке на React.
Пример функционального компонента:
function Welcome(props) {
// Возвращаем JSX-разметку на основе пропсов
return <h1>Привет, {props.name}!</h1>;
}
Вы также можете использовать стрелочные функции:
const Welcome = (props) => {
return <h1>Привет, {props.name}!</h1>;
};
Чем хороши функциональные компоненты
- Просты и лаконичны.
- Понятно, как тестировать и переиспользовать.
- С 2019 года (React 16.8+) могут использовать хуки — функции для работы с состоянием и жизненным циклом.
Классовые компоненты
В более ранних версиях React этот подход был основным. Классовый компонент — это ES6-класс, расширяющий React.Component.
Пример классового компонента:
import React from 'react';
class Welcome extends React.Component {
render() {
// Получаем пропсы через this.props
return <h1>Привет, {this.props.name}!</h1>;
}
}
Отличия классовых компонентов
- Могут использовать внутреннее состояние (
state
) без использования хуков. - Поддерживают методы жизненного цикла (например,
componentDidMount
). - Сейчас чаще используются в больших старых проектах.
Какой тип компонента выбрать
Сейчас рекомендуется использовать функциональные компоненты с хуками. Классы встречаются всё реже.
Создание и использование компонента
React-компоненты обычно располагаются в отдельных файлах, например, Button.js
, и экспортируются с помощью export
. Чаще всего компоненты реализуют следующий подход.
Пример:
// Button.js
function Button(props) {
return <button>{props.text}</button>;
}
export default Button;
Теперь подключим компонент в другом месте:
// App.js
import Button from './Button';
function App() {
return (
<div>
<Button text="Нажми меня" />
</div>
);
}
Здесь мы импортировали компонент и используем его как обычный HTML-тег, передавая пропсы.
Свойства компонента (props)
Props — это входные данные для компонентов, которые передаются как атрибуты. Компонент НЕ должен напрямую изменять props — это только для чтения.
Пример:
function UserCard(props) {
// props.name и props.age приходят от родителя
return (
<div>
<h2>{props.name}</h2>
<p>Возраст: {props.age}</p>
</div>
);
}
// Использование
<UserCard name="Анна" age={28} />
Props позволяют создавать так называемые "детализированные компоненты" — один и тот же компонент можно конфигурировать снаружи.
Деструктуризация props
Часто используется деструктуризация для удобства:
function UserCard({ name, age }) {
return (
<div>
<h2>{name}</h2>
<p>Возраст: {age}</p>
</div>
);
}
Состояние компонента (state)
Иногда компоненту нужно хранить данные, которые могут меняться со временем (например, значение поля ввода или статус переключателя). Для этого используют состояние.
Состояние во Функциональном компоненте
Используется хук useState. Давайте разберем пример:
import React, { useState } from 'react';
function Counter() {
// Счетчик и функция для его изменения
const [count, setCount] = useState(0);
return (
<div>
<p>Вы кликнули {count} раз</p>
<button onClick={() => setCount(count + 1)}>
Кликнуть
</button>
</div>
);
}
// Здесь мы заводим состояние count со значением по умолчанию 0 и функцию setCount для обновления этого состояния.
Состояние в Классовом компоненте
class Counter extends React.Component {
constructor(props) {
super(props);
// Задаем исходное состояние компонента
this.state = { count: 0 };
}
render() {
return (
<div>
<p>Вы кликнули {this.state.count} раз</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Кликнуть
</button>
</div>
);
}
}
// Состояние задается внутри this.state, изменения делаются через this.setState.
Жизненный цикл компонента
Жизненный цикл компонента — это этапы, которые проходит компонент с момента своего создания и до удаления с экрана. Особенно важны методы жизненного цикла для классовых компонентов.
Основные стадии жизненного цикла
- Монтирование (mount)
- Обновление (update)
- Размонтирование (unmount)
Классовые методы жизненного цикла
componentDidMount
— вызывается после первого рендера.componentDidUpdate
— после каждого обновления.componentWillUnmount
— перед удалением компонента.
Функциональные компоненты и useEffect
В функциональных компонентах для работы с "эффектами" используется хук useEffect.
import { useEffect } from 'react';
function Example() {
useEffect(() => {
// Этот код выполнится после монтирования компонента
console.log("Компонент появился на экране");
return () => {
// Этот код при размонтировании
console.log("Компонент удалён с экрана");
};
}, []); // Пустой массив — эффект только при монтировании/размонтировании
return <div>Пример</div>;
}
Вложенность и композиция компонентов
Один компонент может содержать другие — это позволяет создавать сложные структуры из простых строительных блоков.
Пример:
function Dashboard() {
return (
<div>
<Header />
<MainContent />
<Footer />
</div>
);
}
Вы видите, что компонент Dashboard объединяет несколько подкомпонентов. Это удобно — меняя любую из частей, вы не затрагиваете остальные.
Передача функций как props
Вы можете передавать функции в дочерние компоненты как пропсы. Это позволяет дочернему компоненту вызывать функцию в родителе.
Пример:
function Button({ onClick }) {
return <button onClick={onClick}>Клик</button>;
}
function App() {
const handleClick = () => {
alert('Кнопка нажата!');
};
return <Button onClick={handleClick} />;
}
Использование props.children
Специальный проп children
содержит всё, что передано между открывающим и закрывающим тегом вашего компонента.
Пример:
function Card({ children }) {
return <div className="card">{children}</div>;
}
// Использование
<Card>
<h2>Заголовок</h2>
<p>Какой-то текст внутри карточки</p>
</Card>
Так вы можете создавать обёртки для сложных элементов.
Организация компонентов в проекте
Обычно каждый компонент хранится в отдельном файле. Распространённая структура:
- /components
- Header.js
- Footer.js
- Button.js
- ...
Иногда компоненты группируются по функционалу, а не по типу:
- /features
- /Auth
- LoginForm.js
- RegisterForm.js
- /Profile
- ProfileCard.js
- /Auth
- /ui
- Button.js
- Input.js
Это упрощает навигацию и повторное использование.
Кратко о стилизации компонентов
Для стилизации можно использовать:
- Обычные CSS-файлы, подключённые рядом с компонентом.
- CSS-модули с локальной областью видимости стилей.
- CSS-in-JS через библиотеки (emotion, styled-components).
- Inline-стили через атрибут style.
Пример использования CSS-модуля:
// Button.module.css
.button {
background: blue;
color: white;
}
// Button.js
import styles from './Button.module.css';
function Button({ text }) {
return <button className={styles.button}>{text}</button>;
}
Лучшие практики создания компонентов
- Давайте компонентам говорящие имена.
- Выделяйте компоненты избыточной логики — чем меньше обязанностей у компонента, тем проще поддержка.
- Используйте PropTypes или TypeScript для типизации props.
- Оставляйте минимумы состояния — где возможно, используйте props.
- Пишите тесты для компонентов, особенно для переиспользуемых и сложных.
Заключение
Компоненты — это основа проектирования React-приложений. Каждый компонент должен быть изолированным, переиспользуемым и максимально "чистым", то есть получать данные через props и не мутировать их напрямую. Современная разработка на React почти всегда строится на функциональных компонентах и хуках, что делает приложения компактнее и проще для поддержки.
В процессе разработки сложных React-приложений часто возникает необходимость в управлении состоянием приложения и организации роутинга между различными компонентами. Redux Toolkit и React Router являются мощными инструментами, которые помогают справиться с этими задачами. Они позволяют эффективно управлять данными, организовывать навигацию и создавать сложные пользовательские интерфейсы. Чтобы узнать больше о том, как использовать эти инструменты в своих проектах, рекомендуем пройти курс Основы React, React Router и Redux Toolkit. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в основы React уже сегодня.
Частозадаваемые технические вопросы по теме статьи и ответы на них
1. Как пробросить пропсы на несколько уровней вложенности?
Используйте функции обратного вызова (callback props) и пробрасывайте пропсы на каждый уровень. Если нужно передавать значения на очень большой глубине, рассмотрите использование контекста (React Context API). Для этого создайте контекст, оберните верхний компонент в провайдер и используйте useContext в нужных компонентах-потребителях.
2. Как компоненту узнать, был ли он только что добавлен на страницу?
Во функциональных компонентах используйте useEffect с пустым массивом зависимостей. Код внутри useEffect отработает один раз после монтирования. В классовых компонентах используйте метод componentDidMount.
useEffect(() => {
// Код выполнится только при монтировании
}, []);
3. Как передать компоненту по умолчанию содержимое, если children не передан?
Проверьте children на undefined и отобразите запасной вариант:
function MyComponent({ children }) {
return <div>{children || "По умолчанию"}</div>;
}
4. Как добавить обработку событий к элементу внутри компонента?
Передайте функцию-обработчик как проп или объявите её прямо внутри компонента, затем повесьте на нужный DOM-элемент через onClick, onChange и т.д.
<button onClick={handleClick}>Клик</button>
5. Как узнать, почему компонент перерисовывается слишком часто?
Включите инструмент React DevTools и используйте вкладку Profiler для анализа. Также проверьте, не создаёте ли новые объекты/функции на каждом рендере, что может привести к лишним обновлениям. Используйте хуки useMemo, useCallback для оптимизации.
Постройте личный план изучения React до уровня Middle — бесплатно!
React — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по React
Лучшие курсы по теме

React и Redux Toolkit
Антон Ларичев
TypeScript с нуля
Антон Ларичев