Używając TypeScript z Reactem, nie musimy już rozszerzać React.Props
, aby kompilator wiedział, że wszystkie właściwości komponentów reagujących mogą mieć dzieci:
interface MyProps { }
class MyComponent extends React.Component<MyProps, {}> {
public render(): JSX.Element {
return <div>{this.props.children}</div>;
}
}
Jednak wydaje się, że nie ma to miejsca w przypadku bezstanowych komponentów funkcjonalnych:
const MyStatelessComponent = (props: MyProps) => {
return (
<div>{props.children}</div>
);
};
Emituje błąd kompilacji:
Błąd: (102, 17) TS2339: Właściwość „dzieci” nie istnieje w typie „MyProps”.
Wydaje mi się, że dzieje się tak, ponieważ kompilator naprawdę nie może wiedzieć, że children
w argumencie props zostanie podana funkcja waniliowa .
Zatem pytanie brzmi, jak powinniśmy używać dzieci w bezstanowych składnikach funkcjonalnych w TypeScript?
Mógłbym wrócić do starego sposobu MyProps extends React.Props
, ale Props
interfejs jest oznaczony jako przestarzały , a składniki bezstanowe nie mają ani nie obsługują, Props.ref
jak rozumiem.
Mogłem więc children
ręcznie zdefiniować rekwizyt:
interface MyProps {
children?: React.ReactNode;
}
Po pierwsze: czy jest ReactNode
to właściwy typ?
Po drugie: muszę napisać dzieci jako opcjonalne ( ?
), inaczej konsumenci pomyślą, że children
ma to być atrybut komponentu ( <MyStatelessComponent children={} />
) i zgłoszą błąd, jeśli nie otrzymają wartości.
Wygląda na to, że czegoś mi brakuje. Czy ktoś może wyjaśnić, czy moim ostatnim przykładem jest sposób używania bezpaństwowych komponentów funkcjonalnych z dziećmi w Reakcie?
źródło
@types
React.StatelessComponent
/React.SFC
są przestarzałe.React.FunctionComponent
Zamiast tego zaleca się odwołanie .Możesz użyć
React.PropsWithChildren<P>
typu dla swoich rekwizytów:interface MyProps { } function MyComponent(props: React.PropsWithChildren<MyProps>) { return <div>{props.children}</div>; }
źródło
Możesz użyć
interface YourProps { } const yourComponent: React.SFC<YourProps> = props => {}
źródło
Prostsza odpowiedź: użyj
ReactNode
:Jeśli
children
nie jest obowiązkowe, czy nie (czyli posiadające?
lub nie) zależy od komponentu. Jest?
to najbardziej zwięzły sposób wyrażenia tego, więc nie ma w tym nic złego.O historii: To niekoniecznie była prawidłowa odpowiedź, gdy pierwotnie zapytano: Typ
ReactNode
został dodany (prawie) w swojej obecnej formie w marcu 2017 r. Tylko przez to żądanie ściągnięcia , ale prawie wszyscy czytający to dzisiaj powinni korzystać z wystarczająco nowoczesnej wersji React .Na koniec, o przekazywaniu
children
jako „atrybut” (co w języku React oznaczałoby przekazywanie go jako „prop”, a nie atrybut): Jest to możliwe, ale w większości przypadków czyta się lepiej, gdy przekazuje się dzieciom JSX:<MyComponent> <p>This is part of the children.</p> </MyComponent>
czyta łatwiej niż
<MyComponent children={<p>This is part of the children.</p>} />
źródło