> Как использовать типизацию React.FC и почему не указывать children в интерфейсе (React)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Sminex

Стек: React

> Пример ответа

Короткий ответ

React.FC - это тип для функционального компонента, который автоматически добавляет children в пропсы. Начиная с React 18, React.FC не включает children по умолчанию, что решает проблему неявного разрешения передачи дочерних элементов. Явное указание children в интерфейсе делает код более предсказуемым и избегает случайной передачи лишних пропсов.

Подробное объяснение

React.FC (или React.FunctionComponent) - это generic-тип, который типизирует функциональный компонент. В React 17 и ранее он автоматически добавлял children?: ReactNode в пропсы, что часто приводило к неявному разрешению передачи дочерних элементов даже для компонентов, которые их не ожидали. Это нарушало принцип явности TypeScript.

В React 18 поведение изменили: React.FC больше не включает children по умолчанию. Теперь разработчик обязан явно указать children в интерфейсе пропсов, если компонент их использует. Это улучшает читаемость и безопасность типов.

Основные причины не полагаться на React.FC:

  • Явность: компонент должен декларировать, что он принимает children, иначе их передача - ошибка
  • Совместимость: React.FC не поддерживает generic-компоненты и некоторые паттерны (например, defaultProps с типами)
  • Контроль: вы сами решаете, какой тип у children - ReactNode, строка, массив или кастомный тип

Лучшая практика - определять интерфейс пропсов вручную и не использовать React.FC вовсе, особенно в современных проектах.

На практике

В реальных проектах я предпочитаю явно типизировать пропсы без React.FC. Это даёт гибкость: можно использовать union-типы, discriminated unions, generic-параметры. Для компонентов, которые принимают children, я добавляю поле children: ReactNode в интерфейс. Для компонентов без children - не добавляю, и TypeScript подсветит ошибку при попытке передать дочерние элементы.

Такой подход упрощает рефакторинг: если компонент перестаёт использовать children, достаточно удалить поле из интерфейса, и все места передачи children станут ошибочными.

Пример кода

TSX
import { ReactNode } from 'react';
// Плохо: React.FC неявно добавляет children
interface ButtonProps {
onClick: () => void;
}
const BadButton: React.FC<ButtonProps> = ({ onClick }) => (
<button onClick={onClick}>Click</button>
);
// <BadButton onClick={fn}>Text</BadButton> - не ошибка, но children игнорируется
// Хорошо: явное объявление
interface GoodButtonProps {
onClick: () => void;
children: ReactNode;
}
const GoodButton = ({ onClick, children }: GoodButtonProps) => (
<button onClick={onClick}>{children}</button>
);
// <GoodButton onClick={fn}>Text</GoodButton> - корректно
// Компонент без children
interface IconProps {
name: string;
}
const Icon = ({ name }: IconProps) => <span>{name}</span>;
// <Icon name="star">text</Icon> - ошибка, children не ожидается

Как отвечать на собеседовании

Начни с ключевого изменения в React 18: React.FC больше не добавляет children автоматически. Объясни, почему это хорошо - явность и контроль типов. Упомяни, что многие команды отказываются от React.FC в пользу прямого объявления пропсов. Приведи пример, когда неявный children приводил к багам. Подчеркни, что выбор зависит от код-стайла команды, но современный React рекомендует явность.

Что проверяет интервьюер

  • Понимание эволюции React и TypeScript (изменения в React 18)
  • Умение выбирать правильные абстракции, а не слепо следовать шаблонам
  • Знание trade-off между удобством и явностью
  • Способность объяснить, как типизация влияет на поддержку кода

Типичные ошибки

  • Утверждение, что React.FC всегда плох - он полезен для простых компонентов в старых проектах
  • Забывают, что React.FC всё ещё существует и используется в legacy-коде
  • Путают React.FC с React.VFC (устаревший тип для компонентов без children)
  • Не упоминают, что children можно типизировать более строго, чем ReactNode (например, только строки или только элементы определённого типа)

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью