reactjs - Vad är typen på 'children'-egenskapen?
Jag har en mycket enkel funktionell komponent enligt följande:
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => props.children;
export default aux;
Och en annan 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;
Jag fortsätter att få följande felmeddelande:
[ts] JSX-elementtypen 'ReactNode' är inte en konstruktionsfunktion för JSX-element. Typen 'undefined' kan inte tilldelas typen 'ElementClass'. [2605]
Hur skriver jag detta korrekt?
Svar #1
Bara children: React.ReactNode.
Svar #2
För att använda <Aux> i din JSX, behöver det vara en funktion som returnerar ReactElement<any> | null. Det är definitionen av en funktionskomponent.
Men det är för närvarande definierat som en funktion som returnerar React.ReactNode, vilket är en mycket bredare typ. Som React-typningar säger:
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
Se till att de oönskade typerna neutraliseras genom att omsluta det returnerade värdet i en React Fragment (<></>):
const aux: React.FC<AuxProps> = props =>
<>{props.children}</>;
Svar #3
Du kan också använda React.PropsWithChildren<P>.
type ComponentWithChildProps = React.PropsWithChildren<{example?: string}>;
Svar #4
Du kan använda ReactChildren och ReactChild:
import React, { ReactChildren, ReactChild } from 'react';
interface AuxProps {
children: ReactChild | ReactChildren;
}
const Aux = ({ children }: AuxProps) => (<div>{children}</div>);
export default Aux;
Om du behöver skicka platta arrayer av element:
interface AuxProps {
children: ReactChild | ReactChild[] | ReactChildren | ReactChildren[];
}
Svar #5
Det här är vad som fungerade för mig:
interface Props {
children: JSX.Element[] | JSX.Element
}
Redigera Jag skulle rekommendera att använda children: React.ReactNode istället nu.
Svar #6
En React Node är en av följande typer:
Boolean(som ignoreras)nullellerundefined(vilket ignoreras)NumberString- Ett
React-element(resultat avJSX) - En array av någon av ovanstående, möjligen en inbäddad
Svar #7
import { ReactNode, FC } from 'react'
type Props = { children: ReactNode }
const App: FC<Props> = ({children}) => (<div>{children}</div>)
Svar #8
Jag använder följande
type Props = { children: React.ReactNode };
const MyComponent: React.FC<Props> = ({children}) => {
return (
<div>
{ children }
</div>
);
export default MyComponent;
Svar #9
du kan deklarera din komponent så här:
const MyComponent: React.FunctionComponent = (props) => {
return props.children;
}
Svar #10
Returntypen för funktionskomponenten är begränsad till JSXElement | null i TypeScript. Detta är en nuvarande typbegränsning, ren React tillåter fler returntyper.
Minimal demonstrationssnutt
Du kan antingen använda en typförsäkran eller Fragment som en lösning:
const Aux = (props: AuxProps) => <>props.children</>;
const Aux2 = (props: AuxProps) => props.children as ReactElement;
ReactNode
children: React.ReactNode kan vara suboptimalt, om målet är att ha starka typer för Aux.
Nästan allt kan tilldelas den nuvarande ReactNode-typen, vilket är ekvivalent med {} | undefined | null. En säkrare typ för ditt fall kan vara:
interface AuxProps {
children: ReactElement | ReactElement[]
}
Exempel :
Eftersom Aux behöver React-element som children, råkade vi av misstag lägga till en string till den. Då skulle ovanstående lösning ge fel i motsats till ReactNode - ta en titt på de länkade playgrounds.
Typade children är också användbara för icke-JSX props, som en Render Prop-callback.
Svar #11
Det allmänna sättet att hitta vilken typ som helst är genom exempel. Skönheten med TypeScript är att du har tillgång till alla typer, så länge du har de korrekta @types/-filerna.
För att svara på detta själv tänkte jag just på en komponent som React använder som har children-prop. Det första som kom upp i mitt huvud? Vad sägs om en <div />?
Allt du behöver göra är att öppna VSCode och skapa en ny .tsx-fil i ett React-projekt med @types/react.
import React from 'react';
export default () => (
<div children={'test'} />
);
Att hovra över children-prop visar dig typen. Och vad vet du -- Dess typ är ReactNode (ingen anledning till ReactNode[]).
Om du sedan klickar på typdefinitionen tar det dig direkt till definitionen av children som kommer från DOMAttributes-gränssnittet.
// node_modules/@types/react/index.d.ts
interface DOMAttributes<T> {
children?: ReactNode;
...
}
Observera: Denna process bör användas för att hitta vilken okänd typ som helst! Alla finns där och väntar bara på att du ska hitta dem :)
Svar #12
Du kan också använda JSX.ElementChildrenAttribute
export default function Layout({children}: JSX.ElementChildrenAttribute) {
return <div>
{children}
</div>
}
