Как использовать детей с функциональным компонентом React Stateless в TypeScript?
Используя TypeScript с React, нам больше не нужно расширять React.Props
, чтобы компилятор знал, что все реквизиты компонентов компонента могут иметь дочерние элементы:
interface MyProps { }
class MyComponent extends React.Component<MyProps, {}> {
public render(): JSX.Element {
return <div>{this.props.children}</div>;
}
}
Тем не менее, это не похоже на функциональные компоненты без состояния:
const MyStatelessComponent = (props: MyProps) => {
return (
<div>{props.children}</div>
);
};
Выдает ошибку компиляции:
Ошибка: (102, 17) TS2339: свойство 'children' не существует по типу 'MyProps'.
Я предполагаю, что это связано с тем, что компилятор действительно не знает, что в аргументе реквизита будет дана функция ваниль children
.
Итак, вопрос в том, как мы должны использовать детей в функциональном компоненте без состояния в TypeScript?
Я мог бы вернуться к старому способу MyProps extends React.Props
, но интерфейс Props
отмечен как устаревший, а компоненты без гражданства - У меня есть или поддерживаю Props.ref
, насколько я понимаю.
Итак, я могу определить children
prop вручную:
interface MyProps {
children?: React.ReactNode;
}
Во-первых: ReactNode
правильный тип?
Во-вторых: я должен писать дети как необязательные (?
), иначе потребители будут считать, что children
должен быть атрибутом компонента (<MyStatelessComponent children={} />
) и поднять ошибку, если не предоставляется значение.
Кажется, что я чего-то не хватает. Может ли кто-нибудь дать некоторую ясность относительно того, может ли мой последний пример использовать функциональные компоненты без состояния с детьми в React?
Ответы
Ответ 1
Обновление React 16.8: Начиная с React 16.8, имена React.SFC
и React.StatelessComponent
запрещены. На самом деле, они стали псевдонимами React.FunctionComponent
типа или React.FC
для краткости.
Вы бы использовали их так же, хотя:
const MyStatelessComponent : React.FunctionComponent<MyProps> = props =>
<div>
<p>{props.propInMyProps}</p>
<p>{props.children}</p>
</div>
Перед Реакцией 16.8 (Старее):
На данный момент вы можете использовать React.StatelessComponent<>
, так как:
const MyStatelessComponent : React.StatelessComponent<{}> = props =>
<div>{props.children}</div>
Что я добавил там, так это установил тип возвращаемого компонента для типа React.StatelessComponent
.
Для компонента с вашими собственными опорами (например, интерфейс MyProps
):
const MyStatelessComponent : React.StatelessComponent<MyProps> = props =>
<div>
<p>{props.propInMyProps}</p>
<p>{props.children}</p>
</div>
Теперь, props
получил children
собственности, а также те из MyProps
интерфейса.
Я проверил это в машинописной версии 2.0.7
Кроме того, вы можете использовать React.SFC
вместо React.StatelessComponent
для краткости.
Ответ 2
Вы можете использовать React.PropsWithChildren<P>
для своих реквизитов:
interface MyProps { }
function MyComponent(props: React.PropsWithChildren<MyProps>) {
return <div>{props.children}</div>;
}