J'ai un composant fonctionnel très simple comme suit:
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => props.children;
export default aux;
Et un autre composant:
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;
Je continue à recevoir l'erreur suivante:
[ts] Le type d'élément JSX 'ReactNode' n'est pas une fonction de constructeur pour les éléments JSX. Le type 'undefined' n'est pas attribuable au type 'ElementClass'. [2605]
Comment puis-je taper ceci correctement?
JSX.Element
n'est pas assez bon car un enfant React valide pourrait être une chaîne, un booléen, null ...ReactChild
est incomplet aussi pour les mêmes raisonsReactNode
. Cela n'aide pas en termes de sécurité de type, similaire à la saisiechildren
commeany
- voir ma réponse pour une explication.Pour pouvoir l'utiliser
<Aux>
dans votre JSX, il doit s'agir d'une fonction qui renvoieReactElement<any> | null
. C'est la définition d'un composant de fonction .Cependant, il est actuellement défini comme une fonction qui renvoie
React.ReactNode
, qui est un type beaucoup plus large. Comme le disent les typages React:Assurez-vous que les types indésirables sont neutralisés en enveloppant la valeur retournée dans React Fragment (
<></>
):la source
children
un fragment de réaction. Soin d'expliquer? Dans React, c'est parfaitement valable pour justereturn children;
.children
sont un tableau. Si tel est le cas, vous devez les envelopper dans un seul nœud ou utiliser React Fragments.return React.Children.count(children) > 1 ? <>{children}</> : children
:, mais dactylographié s'en plaint. Je l'ai remplacé par juste<>{children}</>
.children
c'est une liste d'éléments qui ne contient qu'un seul élément. Je pense que cela fonctionnerait si vousreturn React.Children.count(children) > 1 ? <>{children}</> : children[0]
faisiez @sanfilippopablo<React.Fragment>
environs,{props.children}
je ne retourne rien.C'est ce qui a fonctionné pour moi:
Modifier Je recommanderais d'utiliser à la
children: React.ReactNode
place maintenant.la source
<MyComponent>{ condition ? <span>test</span> : null}</MyComponent>
. L'utilisationchildren: ReactNode
fonctionnera.vous pouvez déclarer votre composant comme ceci:
la source
Vous pouvez utiliser
ReactChildren
etReactChild
:la source
Depuis le site TypeScript: https://github.com/Microsoft/TypeScript/issues/6471
Cela a fonctionné pour moi. Le nœud enfant peut être de nombreuses choses différentes, donc un typage explicite peut manquer des cas.
Il y a une discussion plus longue sur le problème de suivi ici: https://github.com/Microsoft/TypeScript/issues/13618 , mais l'approche any fonctionne toujours.
la source
Le type de retour du composant de fonction est limité à
JSXElement | null
dans TypeScript. Il s'agit d'une limitation de type actuelle, pure React permet plus de types de retour.Extrait de démonstration minimal
Vous pouvez utiliser une assertion de type ou des fragments comme solution de contournement:
ReactNode
children: React.ReactNode
peut être sous-optimal, si l'objectif est d'avoir des types forts pourAux
.Presque tout peut être attribué au
ReactNode
type actuel , ce qui équivaut à{} | undefined | null
. Un type plus sûr pour votre cas pourrait être:Exemple:
Compte tenu des
Aux
besoins des éléments Reactchildren
, nous y avons accidentellement ajouté unstring
. Ensuite, la solution ci-dessus serait une erreur par rapport àReactNode
- jetez un œil aux terrains de jeux liés.Les caractères typés
children
sont également utiles pour les accessoires non JSX, comme un rappel Render Prop .la source
Vous pouvez également utiliser
React.PropsWithChildren<P>
.la source
La manière générale de trouver n'importe quel type est par exemple. La beauté de la dactylographie est que vous avez accès à tous les types, tant que vous avez les bons
@types/
fichiers.Pour y répondre moi-même, je viens de penser à un composant qui utilise un
children
accessoire. La première chose qui vous est venue à l'esprit? Et un<div />
?Tout ce que vous avez à faire est d'ouvrir vscode et de créer un nouveau
.tsx
fichier dans un projet react avec@types/react
.Le survol de l'
children
accessoire vous montre le type. Et que savez-vous - Son type estReactNode
(pas besoin deReactNode[]
).Ensuite, si vous cliquez dans la définition de type, cela vous amène directement à la définition de la
children
provenance de l'DOMAttributes
interface.la source
En tant que type contenant des enfants, j'utilise:
Ce type de conteneur enfants est suffisamment générique pour prendre en charge tous les différents cas et également aligné avec l'API ReactJS.
Donc, pour votre exemple, ce serait quelque chose comme:
la source
Ces réponses semblent obsolètes - React a maintenant un type intégré
PropsWithChildren<{}>
. Il est défini de la même manière que certaines des bonnes réponses sur cette page:type PropsWithChildren<P> = P & { children?: ReactNode };
la source
P
-il de ce type?P
est le type d'accessoires de votre composantLes composants React doivent avoir un seul nœud wrapper ou renvoyer un tableau de nœuds.
Votre
<Aux>...</Aux>
composant a deux nœudsdiv
etmain
.Essayez d'envelopper vos enfants dans un composant
div
inAux
.la source