В чем разница между классовыми и функциональными компонентами в React?
Компоненты
Это два способа объявления компонентов. Сегодня стандарт — функциональные с хуками; классовые остаются в легаси-коде и в Error Boundaries.
Классовые компоненты
class Counter extends React.Component {
state = { count: 0 };
componentDidMount() { document.title = this.state.count; }
render() {
return <button onClick={() => this.setState({ count: this.state.count + 1 })}>
{this.state.count}
</button>;
}
}- Состояние — объект
this.state, обновление черезthis.setState(мерджит поля). - Побочные эффекты — методы жизненного цикла (componentDidMount и др.).
- Проблемы:
thisи биндинг, логика одного эффекта размазана по нескольким методам, переиспользование логики только через HOC/render props.
Функциональные компоненты
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => { document.title = count; }, [count]);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
};- Состояние и эффекты — хуки (useState, useEffect и т.д.).
- Связанная логика собрана в одном месте и выносится в кастомные хуки.
- Нет
this, меньше кода, проще типизировать и тестировать.
Отличия
- Состояние: объект + setState с мерджем против отдельных useState с заменой значения.
- Эффекты: методы жизненного цикла против useEffect с зависимостями.
- Переиспользование логики: HOC/render props против кастомных хуков.
- Захват значений: в функциях каждый рендер «замыкает» свои props/state; в классах
this.propsвсегда актуальные — отсюда разное поведение в асинхронном коде.
Что осталось только в классах
Error Boundaries (componentDidCatch / getDerivedStateFromError) — функционального аналога пока нет, обычно берут готовый компонент (react-error-boundary).
Коротко для собеседования
Функциональные компоненты с хуками — современный стандарт: меньше кода, логика группируется по смыслу и переиспользуется через кастомные хуки, нет проблем с this. Классовые — легаси; практически единственный кейс, где класс необходим, — Error Boundary.