> Как использовать типизацию 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 станут ошибочными.
Пример кода
TSXimport { ReactNode } from 'react';// Плохо: React.FC неявно добавляет childreninterface 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> - корректно// Компонент без childreninterface 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(например, только строки или только элементы определённого типа)
> Похожие задачи по frontend
Какие подходы в Angular, React и Svelte вам ближе
Почему для внешних функций не нужен массив зависимостей в useEffect?
Как React получает данные из input
Как сделать так, чтобы React компонент рендерился только при изменении определенного пропса
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью