PassFront
  1. PassFront
  2. База знаний
  3. Компоненты

В чем разница между классовыми и функциональными компонентами в 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.

Другие вопросы раздела