Come utilizzare i bambini con il componente funzionale stateless React in TypeScript?


88

Usando TypeScript con React non dobbiamo più estendere React.Propsaffinché il compilatore sappia che tutti gli oggetti di scena del componente react possono avere figli:

interface MyProps { }

class MyComponent extends React.Component<MyProps, {}> {
  public render(): JSX.Element {
    return <div>{this.props.children}</div>;
  }
}

Tuttavia, non sembra essere il caso dei componenti funzionali apolidi:

const MyStatelessComponent = (props: MyProps) => {
  return (
    <div>{props.children}</div>
  );
};

Emette l'errore di compilazione:

Errore: (102, 17) TS2339: la proprietà "figli" non esiste nel tipo "MyProps".

Immagino che questo sia perché non c'è davvero alcun modo per il compilatore di sapere che una funzione vanilla verrà fornita childrennell'argomento props.

Quindi la domanda è: come dovremmo usare i bambini in un componente funzionale senza stato in TypeScript?

Potrei tornare al vecchio modo di MyProps extends React.Props, ma l' Propsinterfaccia è contrassegnata come deprecata e i componenti stateless non hanno o supportano un Props.refcome ho capito.

Quindi potrei definire l' childrenelica manualmente:

interface MyProps {
  children?: React.ReactNode;
}

Primo: è ReactNodeil tipo corretto?

Secondo: devo scrivere children come optional ( ?) altrimenti i consumatori penseranno che childrendovrebbe essere un attributo del component ( <MyStatelessComponent children={} />) e solleveranno un errore se non viene fornito un valore.

Sembra che mi manchi qualcosa. Qualcuno può fornire un po 'di chiarezza sul fatto che il mio ultimo esempio sia il modo di utilizzare componenti funzionali apolidi con i bambini in React?

Risposte:


89

Aggiornamento di React 16.8: a partire da React 16.8, i nomi React.SFCe React.StatelessComponentsono deprecati. In realtà, sono diventati alias per React.FunctionComponenttipo o React.FCabbreviazione.

Li useresti allo stesso modo però:

const MyStatelessComponent : React.FunctionComponent<MyProps> = props =>
    <div>
        <p>{props.propInMyProps}</p>
        <p>{props.children}</p>
    </div>

Prima di reagire 16.8 (meno recente):

Per ora, puoi usare il React.StatelessComponent<>tipo, come:

const MyStatelessComponent : React.StatelessComponent<{}> = props =>
    <div>{props.children}</div>

Quello che ho aggiunto è l'impostazione del tipo di ritorno del componente su React.StatelessComponent digitare.

Per un componente con i tuoi oggetti di scena personalizzati (come l' MyPropsinterfaccia):

const MyStatelessComponent : React.StatelessComponent<MyProps> = props =>
    <div>
        <p>{props.propInMyProps}</p>
        <p>{props.children}</p>
    </div>

Ora, propsha le childrenproprietà così come quelle MyPropsdell'interfaccia.

L'ho controllato nella versione dattiloscritta 2.0.7

Inoltre, puoi usare React.SFCinvece di React.StatelessComponentper brevità.


Grazie! Sembra che io sia su una vecchia versione della digitazione che non lo supporta ... Immagino sia ora di stringere i denti e usare TS 2.0 con@types
Aaron Beall

3
React.StatelessComponent/ React.SFCsono deprecati. Si consiglia invece di fare riferimento a React.FunctionComponent.
Alexander Kachkaev

Nota che questo metodo non funziona se hai un componente generico
FunkeyFlo

94

Puoi usare il React.PropsWithChildren<P>tipo per i tuoi oggetti di scena:

interface MyProps { }

function MyComponent(props: React.PropsWithChildren<MyProps>) {
  return <div>{props.children}</div>;
}

0

Puoi usare

interface YourProps { }
const yourComponent: React.SFC<YourProps> = props => {}

React.SFCè deprecato
Arjan

0

Risposta più semplice: usa ReactNode:

interface MyProps {
  children?: React.ReactNode
}

Se childrenè opzionale o no (cioè avere ?o meno) dipende dal tuo componente. Il ?è il modo conciso più per esprimere che, così sbagliato nulla con quello.

Sulla storia: questa non era necessariamente la risposta corretta quando è stato inizialmente chiesto: il tipo è ReactNodestato aggiunto nella (quasi) sua forma attuale nel marzo 2017 solo da questa richiesta di pull , ma quasi tutti quelli che leggono questo oggi dovrebbero essere su una versione abbastanza moderna di React .

Infine, sul passare childrencome "attributo" (che, nel gergo di React, lo passerebbe come "prop", non attributo): è possibile, ma nella maggior parte dei casi si legge meglio quando si passano figli JSX:

<MyComponent>
  <p>This is part of the children.</p>
</MyComponent>

legge più facilmente di

<MyComponent children={<p>This is part of the children.</p>} />

0

Puoi semplicemente aggiungere figli al componente e se è connesso a un contenitore è tutto ciò di cui hai bisogno.

const MyComponent = ({ 
   children  
}) => {
  return <div>{children}</div>

}

Perché aggiungere un'altra risposta a una domanda così vecchia?
Mike Szyndel

Ed era una domanda TypeScript.
Zsolt Meszaros
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.