Чем отличается функциональный компонент от классового?

В 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 &lt;Text&gt;{this.props.title}&lt;/Text&gt;;
}
}

Работа с state

В функциональных компонентах:

Состояние реализуется с помощью хука useState:

import React, { useState } from 'react';
function Counter() {
const \[count, setCount\] = useState(0);
return (
&lt;View&gt;
&lt;Text&gt;{count}&lt;/Text&gt;
&lt;Button title="Добавить" onPress={() =&gt; setCount(count + 1)} />
&lt;/View&gt;
);
}

В классовых компонентах:

Состояние задаётся в 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 (
&lt;View&gt;
&lt;Text&gt;{this.state.count}&lt;/Text&gt;
&lt;Button title="Добавить" onPress={this.increment} /&gt;
&lt;/View&gt;
);
}
}

Жизненный цикл компонента

В классовых компонентах:

Есть специальные методы жизненного цикла:

  • constructor() — инициализация

  • componentDidMount() — вызывается после монтирования

  • componentDidUpdate() — после обновления

  • componentWillUnmount() — перед удалением

Пример:

class Timer extends React.Component {
componentDidMount() {
this.interval = setInterval(() => {
console.log('тик');
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return &lt;Text&gt;Таймер работает&lt;/Text&gt;;
}
}

В функциональных компонентах:

Жизненный цикл реализуется с помощью хука useEffect:

import React, { useEffect } from 'react';
function Timer() {
useEffect(() => {
const interval = setInterval(() => {
console.log('тик');
}, 1000);
return () => clearInterval(interval); // аналог componentWillUnmount
}, \[\]);
return &lt;Text&gt;Таймер работает&lt;/Text&gt;;
}

Хук useEffect может выполнять действия:

  • при монтировании (если передать пустой массив зависимостей),

  • при обновлении (если указать зависимости),

  • при размонтировании (если вернуть функцию очистки).

Обработка событий

Оба компонента используют одинаковый механизм обработки событий (onPress, onChangeText и т.д.), но классы чаще требуют привязки контекста this:

В функциональном компоненте:

function ButtonExample() {
const handleClick = () => {
console.log('Нажато');
};
return &lt;Button title="Нажми" onPress={handleClick} /&gt;;
}

В классовом компоненте:

class ButtonExample extends React.Component {
handleClick = () => {
console.log('Нажато');
};
render() {
return &lt;Button title="Нажми" onPress={this.handleClick} /&gt;;
}
}

Если использовать обычный метод (handleClick() {}), нужно вручную привязывать this в конструкторе.

Использование хуков (только в функциональных компонентах)

Хуки — это функции, добавляющие функциональность функциональным компонентам. Их нельзя использовать в классах.

Некоторые из часто используемых хуков:

  • useState — для локального состояния

  • useEffect — для побочных эффектов

  • useContext — доступ к контексту

  • useRef — работа с mutable ссылками

  • useMemo, useCallback — оптимизация производительности

Контекст и функциональные компоненты

Функциональные компоненты могут использовать useContext для доступа к контексту без обёртки Consumer.

const ThemeContext = React.createContext();
function ThemedComponent() {
const theme = useContext(ThemeContext);
return &lt;Text style={{ color: theme.color }}&gt;Пример&lt;/Text&gt;;
}

В классах:

class ThemedComponent extends React.Component {
static contextType = ThemeContext;
render() {
return &lt;Text style={{ color: this.context.color }}&gt;Пример&lt;/Text&gt;;
}
}

Краткое сравнение

Характеристика Функциональный компонент Классовый компонент
Синтаксис Функция Класс
--- --- ---
Доступ к state Через useState() Через this.state и this.setState()
--- --- ---
Жизненный цикл Через useEffect() и другие хуки Через методы (componentDidMount, и т.д.)
--- --- ---
Контекст useContext() static contextType или Context.Consumer
--- --- ---
Хуки Да (любые хуки) Нет
--- --- ---
Обработка событий Без this, проще Требуется this, часто привязка
--- --- ---
Лёгкость и компактность Минимальный шаблон, лаконичный код Более громоздкий, особенно с жизненным циклом
--- --- ---
Переиспользуемость логики Высокая (через хуки, custom hooks) Ограниченная
--- --- ---
Совместимость Совместимы с современными фичами React Устаревают, но всё ещё поддерживаются
--- --- ---

Когда использовать каждый

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

React Team официально рекомендует использовать функциональные компоненты и хуки как предпочтительный подход к разработке.