Mam bardzo prosty element funkcjonalny, jak następuje:
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => props.children;
export default aux;
I kolejny komponent:
import * as React from "react";
export interface LayoutProps {
children: React.ReactNode
}
const layout = (props: LayoutProps) => (
<Aux>
<div>Toolbar, SideDrawer, Backdrop</div>
<main>
{props.children}
</main>
<Aux/>
);
export default layout;
Ciągle otrzymuję następujący błąd:
[ts] Typ elementu JSX „ReactNode” nie jest funkcją konstruktora dla elementów JSX. Typu „undefined” nie można przypisać do typu „ElementClass”. [2605]
Jak mam to poprawnie wpisać?
reactjs
typescript
jsx
typescript2.0
Asool
źródło
źródło
JSX.Element
nie jest wystarczająco dobry, ponieważ prawidłowe dzieci React mogą być ciągiem znaków, wartością logiczną, wartością zerową ...ReactChild
jest również niekompletne z tych samych powodówReactNode
. Nie pomaga to pod względem bezpieczeństwa typów, podobnie jak pisaniechildren
jakoany
- zobacz moją odpowiedź po wyjaśnienie.Aby użyć go
<Aux>
w JSX, musi to być funkcja, która zwracaReactElement<any> | null
. To jest definicja składnika funkcji .Jednak obecnie jest zdefiniowana jako funkcja zwracająca
React.ReactNode
, która jest typem znacznie szerszym. Jak mówią typy React:Upewnij się, że niechciane typy są zneutralizowane, opakowując zwracaną wartość w React Fragment (
<></>
):źródło
children
fragment reakcji. Chcesz wyjaśnić? W React jest to całkowicie ważnereturn children;
.children
są tablicą. W takim przypadku musisz zawinąć je w pojedynczy węzeł lub użyć fragmentów React.return React.Children.count(children) > 1 ? <>{children}</> : children
:, ale maszynopis narzeka na to. Zastąpiłem go po prostu<>{children}</>
.children
jest to lista elementów, która tak się składa, że zawiera tylko 1 element. Myślę, że zadziałałoby, gdybyś to zrobiłreturn React.Children.count(children) > 1 ? <>{children}</> : children[0]
@sanfilippopablo<React.Fragment>
otoczeniu{props.children}
nic nie zwracam.Oto, co zadziałało dla mnie:
Edytuj Polecam używać
children: React.ReactNode
zamiast tego teraz.źródło
<MyComponent>{ condition ? <span>test</span> : null}</MyComponent>
. Używaniechildren: ReactNode
będzie działać.możesz zadeklarować swój komponent w ten sposób:
źródło
Możesz użyć
ReactChildren
iReactChild
:źródło
Z witryny TypeScript: https://github.com/Microsoft/TypeScript/issues/6471
To zadziałało dla mnie. Węzeł potomny może mieć wiele różnych cech, więc jawne wpisywanie może pomijać przypadki.
Dłuższa dyskusja na temat następującego problemu jest tutaj: https://github.com/Microsoft/TypeScript/issues/13618 , ale każde podejście nadal działa.
źródło
Typ zwracany składnika funkcji jest ograniczony do
JSXElement | null
w TypeScript. Jest to aktualne ograniczenie typu, czysty React pozwala na więcej typów zwracanych.Minimalny fragment demonstracyjny
Możesz użyć asercji typu lub fragmentów jako obejścia:
ReactNode
children: React.ReactNode
może być nieoptymalny, jeśli celem jest posiadanie silnych typówAux
.Prawie wszystko można przypisać do bieżącego
ReactNode
typu, co jest równoważne{} | undefined | null
. Bezpieczniejszym typem dla Twojego przypadku może być:Przykład:
Biorąc pod uwagę
Aux
potrzeby elementy React aschildren
, przypadkowo dodaliśmystring
do niego a. Wtedy powyższe rozwiązanie byłoby błędem w przeciwieństwie doReactNode
- spójrz na połączone place zabaw.Typy
children
są również przydatne w przypadku właściwości innych niż JSX, takich jak wywołanie zwrotne właściwości renderowania .źródło
Możesz także użyć
React.PropsWithChildren<P>
.źródło
Ogólny sposób znaleźć każdy rodzaj jest dobry przykład. Piękno maszynopisu polega na tym, że masz dostęp do wszystkich typów, o ile masz poprawną
@types/
pliki.Aby odpowiedzieć sobie na to pytanie, pomyślałem, że komponent reaguje, który ma właściwości
children
. Pierwsza rzecz, która przyszła mi do głowy? Co powiesz na<div />
?Wszystko, co musisz zrobić, to otworzyć vscode i utworzyć nowy
.tsx
plik w projekcie React z@types/react
.Najechanie kursorem na
children
rekwizyt pokazuje typ. A co wiesz - jego typ jestReactNode
(nie ma potrzebyReactNode[]
).Następnie, jeśli klikniesz na definicję typu, przejdziesz bezpośrednio do definicji
children
pochodzącej zDOMAttributes
interfejsu.źródło
Jako typ zawierający dzieci używam:
Ten typ kontenera podrzędnego jest wystarczająco ogólny, aby obsługiwać wszystkie różne przypadki, a także dostosowany do interfejsu API ReactJS.
Na przykład będzie to coś takiego:
źródło
Te odpowiedzi wydają się być nieaktualne - React ma teraz wbudowany typ
PropsWithChildren<{}>
. Jest definiowany podobnie do niektórych poprawnych odpowiedzi na tej stronie:type PropsWithChildren<P> = P & { children?: ReactNode };
źródło
P
w przypadku tego typu?P
to typ rekwizytów twojego komponentuKomponenty React powinny mieć pojedynczy węzeł opakowujący lub zwracać tablicę węzłów.
Twój
<Aux>...</Aux>
komponent ma dwa węzłydiv
imain
.Spróbuj owinąć swoje dzieci
div
wAux
komponent.źródło