Чем отличается функциональный компонент от классового?
В React существует два типа компонентов: функциональные компоненты и классовые компоненты. Оба типа используются для создания пользовательских интерфейсов, однако между ними есть существенные различия в синтаксисе, способах управления состоянием, жизненном цикле и подходах к архитектуре приложения.
История вопроса
Первоначально React был ориентирован на классовые компоненты, так как только они позволяли работать со состоянием (state) и методами жизненного цикла (componentDidMount, shouldComponentUpdate и т.д.).
Функциональные компоненты были "глупыми" — просто принимали props и возвращали JSX.
С появлением хуков в React 16.8 (2019 год), функциональные компоненты получили доступ ко всем возможностям классовых, включая state, context, жизненный цикл и побочные эффекты. Это сделало их предпочтительным способом написания компонентов в большинстве современных проектов.
Синтаксис
Функциональный компонент
Функциональные компоненты — это обычные JavaScript-функции, которые принимают props как аргумент и возвращают JSX.
function Welcome(props) {
return <Text>Привет, {props.name}</Text>;
}
Можно использовать стрелочную функцию:
const Welcome = ({ name }) => <Text>Привет, {name}</Text>;
Классовый компонент
Классовый компонент создаётся с использованием ключевого слова class и расширяет React.Component. Обязательно реализуется метод render().
class Welcome extends React.Component {
render() {
return <Text>Привет, {this.props.name}</Text>;
}
}
Работа с props
Оба типа компонентов могут принимать props. Однако синтаксис отличается:
В функциональных компонентах props передаются как аргумент:
```python
function Component(props) {
return <Text>{props.title}</Text>;
}
В классовых компонентах доступ к props идёт через this.props:
<br/>```python
class Component extends React.Component {
render() {
return <Text>{this.props.title}</Text>;
}
}
Работа с state
В функциональных компонентах:
Состояние реализуется с помощью хука useState:
import React, { useState } from 'react';
function Counter() {
const \[count, setCount\] = useState(0);
return (
<View>
<Text>{count}</Text>
<Button title="Добавить" onPress={() => setCount(count + 1)} />
</View>
);
}
В классовых компонентах:
Состояние задаётся в this.state и изменяется с помощью this.setState():
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<View>
<Text>{this.state.count}</Text>
<Button title="Добавить" onPress={this.increment} />
</View>
);
}
}
Жизненный цикл компонента
В классовых компонентах:
Есть специальные методы жизненного цикла:
-
constructor() — инициализация
-
componentDidMount() — вызывается после монтирования
-
componentDidUpdate() — после обновления
-
componentWillUnmount() — перед удалением
Пример:
class Timer extends React.Component {
componentDidMount() {
this.interval = setInterval(() => {
console.log('тик');
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return <Text>Таймер работает</Text>;
}
}
В функциональных компонентах:
Жизненный цикл реализуется с помощью хука useEffect:
import React, { useEffect } from 'react';
function Timer() {
useEffect(() => {
const interval = setInterval(() => {
console.log('тик');
}, 1000);
return () => clearInterval(interval); // аналог componentWillUnmount
}, \[\]);
return <Text>Таймер работает</Text>;
}
Хук useEffect может выполнять действия:
-
при монтировании (если передать пустой массив зависимостей),
-
при обновлении (если указать зависимости),
-
при размонтировании (если вернуть функцию очистки).
Обработка событий
Оба компонента используют одинаковый механизм обработки событий (onPress, onChangeText и т.д.), но классы чаще требуют привязки контекста this:
В функциональном компоненте:
function ButtonExample() {
const handleClick = () => {
console.log('Нажато');
};
return <Button title="Нажми" onPress={handleClick} />;
}
В классовом компоненте:
class ButtonExample extends React.Component {
handleClick = () => {
console.log('Нажато');
};
render() {
return <Button title="Нажми" onPress={this.handleClick} />;
}
}
Если использовать обычный метод (handleClick() {}), нужно вручную привязывать this в конструкторе.
Использование хуков (только в функциональных компонентах)
Хуки — это функции, добавляющие функциональность функциональным компонентам. Их нельзя использовать в классах.
Некоторые из часто используемых хуков:
-
useState — для локального состояния
-
useEffect — для побочных эффектов
-
useContext — доступ к контексту
-
useRef — работа с mutable ссылками
-
useMemo, useCallback — оптимизация производительности
Контекст и функциональные компоненты
Функциональные компоненты могут использовать useContext для доступа к контексту без обёртки Consumer.
const ThemeContext = React.createContext();
function ThemedComponent() {
const theme = useContext(ThemeContext);
return <Text style={{ color: theme.color }}>Пример</Text>;
}
В классах:
class ThemedComponent extends React.Component {
static contextType = ThemeContext;
render() {
return <Text style={{ color: this.context.color }}>Пример</Text>;
}
}
Краткое сравнение
Характеристика | Функциональный компонент | Классовый компонент |
---|---|---|
Синтаксис | Функция | Класс |
--- | --- | --- |
Доступ к state | Через useState() | Через this.state и this.setState() |
--- | --- | --- |
Жизненный цикл | Через useEffect() и другие хуки | Через методы (componentDidMount, и т.д.) |
--- | --- | --- |
Контекст | useContext() | static contextType или Context.Consumer |
--- | --- | --- |
Хуки | Да (любые хуки) | Нет |
--- | --- | --- |
Обработка событий | Без this, проще | Требуется this, часто привязка |
--- | --- | --- |
Лёгкость и компактность | Минимальный шаблон, лаконичный код | Более громоздкий, особенно с жизненным циклом |
--- | --- | --- |
Переиспользуемость логики | Высокая (через хуки, custom hooks) | Ограниченная |
--- | --- | --- |
Совместимость | Совместимы с современными фичами React | Устаревают, но всё ещё поддерживаются |
--- | --- | --- |
Когда использовать каждый
С появлением хуков большинство новых компонентов создаются как функциональные. Классы используются реже, в основном в старом коде или библиотеках, написанных до 2019 года.
Функциональные компоненты обеспечивают более чистую, декларативную и модульную архитектуру.
React Team официально рекомендует использовать функциональные компоненты и хуки как предпочтительный подход к разработке.