Ich habe eine sehr einfache Funktionskomponente wie folgt:
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => props.children;
export default aux;
Und noch eine Komponente:
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;
Ich erhalte immer wieder den folgenden Fehler:
[ts] Der JSX-Elementtyp 'ReactNode' ist keine Konstruktorfunktion für JSX-Elemente. Der Typ 'undefined' kann nicht dem Typ 'ElementClass' zugewiesen werden. [2605]
Wie tippe ich das richtig?
reactjs
typescript
jsx
typescript2.0
Asool
quelle
quelle
JSX.Element
ist nicht gut genug, da ein gültiges React-Kind eine Zeichenfolge sein kann, ein BoolescherReactChild
ReactNode
. Es hilft nicht in Bezug auf die Typensicherheit, ähnlich wie beim Tippenchildren
alsany
- siehe meine Antwort für eine Erklärung.Um
<Aux>
in Ihrem JSX verwendet zu werden, muss es eine Funktion sein, die zurückgibtReactElement<any> | null
. Das ist die Definition einer Funktionskomponente .Derzeit ist es jedoch als eine Funktion definiert, die zurückgibt
React.ReactNode
, was ein viel breiterer Typ ist. Wie React-Eingaben sagen:Stellen Sie sicher, dass die unerwünschten Typen neutralisiert werden, indem Sie den zurückgegebenen Wert in React Fragment (
<></>
) einschließen :quelle
children
ein Reaktionsfragment einzuschließen. Möchtest du das erklären? In React ist es vollkommen gültig, nurreturn children;
.children
es sich um ein Array handelt. Wenn dies der Fall ist, müssen Sie sie entweder in einen einzelnen Knoten einschließen oder "Fragmente reagieren" verwenden.return React.Children.count(children) > 1 ? <>{children}</> : children
:, aber Typoskript beschwert sich darüber. Ich habe es durch nur ersetzt<>{children}</>
.children
es sich um eine Liste von Elementen handelt, die zufällig nur 1 Element enthalten. Ich denke, es würde funktionieren, wenn Siereturn React.Children.count(children) > 1 ? <>{children}</> : children[0]
@sanfilippopablo<React.Fragment>
Umgebung{props.children}
gebe ich nichts zurück.Das hat bei mir funktioniert:
Bearbeiten Ich würde empfehlen,
children: React.ReactNode
stattdessen jetzt zu verwenden.quelle
<MyComponent>{ condition ? <span>test</span> : null}</MyComponent>
. Verwendenchildren: ReactNode
wird funktionieren.Sie können Ihre Komponente folgendermaßen deklarieren:
quelle
Sie können verwenden
ReactChildren
undReactChild
:quelle
Von der TypeScript-Site: https://github.com/Microsoft/TypeScript/issues/6471
Das hat bei mir funktioniert. Der untergeordnete Knoten kann viele verschiedene Dinge sein, so dass bei der expliziten Eingabe Fälle übersehen werden können.
Es gibt hier eine längere Diskussion zum Folgeproblem: https://github.com/Microsoft/TypeScript/issues/13618 , aber jeder Ansatz funktioniert immer noch.
quelle
Der Rückgabetyp der Funktionskomponente ist
JSXElement | null
in TypeScript beschränkt. Dies ist eine aktuelle Typbeschränkung. Pure React ermöglicht mehr Rückgabetypen.Minimaler Demonstrationsausschnitt
Sie können entweder eine Typzusicherung oder Fragmente als Problemumgehung verwenden:
ReactNode
children: React.ReactNode
könnte suboptimal sein, wenn das Ziel darin besteht, starke Typen für zu habenAux
.Dem aktuellen
ReactNode
Typ kann fast alles zugeordnet werden , was äquivalent zu ist{} | undefined | null
. Ein sicherer Typ für Ihren Fall könnte sein:Beispiel:
Gegebene
Aux
Bedürfnisse Reagieren Sie Elemente alschildren
, wir haben versehentlich ein hinzugefügtstring
. Dann würde die obige Lösung im Gegensatz zuReactNode
- werfen Sie einen Blick auf die verknüpften Spielplätze.Typisiert
children
sind auch nützlich für Nicht-JSX-Requisiten wie einen Render Prop- Rückruf.quelle
Sie können auch verwenden
React.PropsWithChildren<P>
.quelle
Der allgemeine Weg, einen Typ zu finden, ist beispielhaft. Das Schöne an Typoskript ist, dass Sie Zugriff auf alle Typen haben, solange Sie über die richtigen
@types/
Dateien verfügen .Um dies selbst zu beantworten, dachte ich nur an eine Komponente, die die
children
Requisite verwendet. Das erste, was mir in den Sinn kam? Wie wäre es mit einem<div />
?Alles was Sie tun müssen, ist vscode zu öffnen und eine neue
.tsx
Datei in einem Reaktionsprojekt mit zu erstellen@types/react
.Wenn
children
Sie mit der Maus über die Requisite fahren, sehen Sie den Typ. Und was weißt du - sein Typ istReactNode
(keine Notwendigkeit fürReactNode[]
).Dann , wenn Sie die Typdefinition klicken hinein bringt Sie direkt in die Definition des Begriffs
children
kommenDOMAttributes
Schnittstelle.quelle
Als Typ, der Kinder enthält, verwende ich:
Dieser untergeordnete Containertyp ist generisch genug, um alle verschiedenen Fälle zu unterstützen, und auch an der ReactJS-API ausgerichtet.
Für Ihr Beispiel wäre es also ungefähr so:
quelle
Diese Antworten scheinen veraltet zu sein - React verfügt jetzt über einen integrierten Typ
PropsWithChildren<{}>
. Es ist ähnlich wie einige der richtigen Antworten auf dieser Seite definiert:type PropsWithChildren<P> = P & { children?: ReactNode };
quelle
P
bei diesem Typ?P
ist der Typ der Requisiten Ihrer KomponenteReaktionskomponenten sollten einen einzelnen Wrapper-Knoten haben oder ein Array von Knoten zurückgeben.
Ihre
<Aux>...</Aux>
Komponente hat zwei Knotendiv
undmain
.Versuchen Sie, Ihre Kinder in eine
div
In-Aux
Komponente zu wickeln .quelle