Разбери, может ли функциональный компонент повторить весь функционал классового: в каких случаях и от чего это зависит.
Компоненты
Почти весь функционал классового компонента функциональный повторяет — как правило, проще. Исключений на сегодня два, и оба закрываются обходными путями.
Что повторяется полностью
- Состояние: this.state/setState → useState/useReducer (с нюансом: сеттер заменяет значение, а не мерджит — при желании мердж пишется вручную).
- Жизненный цикл: componentDidMount/DidUpdate/WillUnmount → useEffect с разными deps + cleanup; getSnapshotBeforeUpdate-подобные сценарии → useLayoutEffect.
- shouldComponentUpdate / PureComponent → React.memo (+ кастомный компаратор).
- Инстанс-поля (this.timer) → useRef.
- Контекст, ref-forwarding, порталы — есть в обеих моделях.
- Переиспользование логики — у функций даже лучше: кастомные хуки вместо HOC/render props.
Что функциональный компонент НЕ может сам
Error Boundary. Аналогов componentDidCatch / getDerivedStateFromError в хуках нет. Обход: один классовый компонент-граница (или react-error-boundary) оборачивает функциональное приложение — писать классы для этого каждый раз не нужно.
getSnapshotBeforeUpdate — точного эквивалента нет; частично закрывается useLayoutEffect (читать DOM до отрисовки кадра), но «до применения изменений к DOM» — только в классах. Нужен крайне редко (сохранение позиции скролла в чатах).
От чего это зависит
От версии React: с 16.8 (хуки) паритет почти полный; React 19 добавил ref-как-проп (без forwardRef). Если появятся хуки для ошибок (обсуждаются давно) — исключения исчезнут совсем.
Коротко для собеседования
Да, за двумя исключениями: Error Boundaries (componentDidCatch — только классы; на практике одна классовая обёртка или react-error-boundary) и getSnapshotBeforeUpdate (частично заменяется useLayoutEffect). Всё остальное — state, жизненный цикл, оптимизации, refs — хуки покрывают, и обычно компактнее.