Como usar crianças com React Stateless Functional Component no TypeScript?


88

Usando o TypeScript com React, não precisamos mais estender React.Propspara que o compilador saiba que todos os adereços do componente react podem ter filhos:

interface MyProps { }

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

No entanto, não parece ser o caso para componentes funcionais sem estado:

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

Emite o erro de compilação:

Erro: (102, 17) TS2339: A propriedade 'filhos' não existe no tipo 'MyProps'.

Acho que é porque realmente não há como o compilador saber que uma função vanilla será fornecida childrenno argumento props.

Portanto, a questão é como devemos usar filhos em um componente funcional sem estado no TypeScript?

Eu poderia voltar ao modo antigo MyProps extends React.Props, mas a Propsinterface está marcada como obsoleta e os componentes sem estado não têm ou suportam um, Props.refconforme eu o entendo.

Então, eu poderia definir o childrenadereço manualmente:

interface MyProps {
  children?: React.ReactNode;
}

Primeiro: é ReactNodeo tipo correto?

Segundo: tenho que escrever filhos como opcionais ( ?) ou então os consumidores pensarão que isso childrené um atributo do componente ( <MyStatelessComponent children={} />) e gerarão um erro se não for fornecido com um valor.

Parece que estou faltando alguma coisa. Alguém pode esclarecer se meu último exemplo é a maneira de usar componentes funcionais sem estado com crianças no React?

Respostas:


89

Atualização do React 16.8: Desde o React 16.8, os nomes React.SFCe React.StatelessComponentestão obsoletos. Na verdade, eles se tornaram apelidos para React.FunctionComponenttipo ou React.FCabreviatura.

Você os usaria da mesma maneira:

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

Antes de reagir 16.8 (mais antigos):

Por enquanto, você pode usar o React.StatelessComponent<>tipo, como:

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

O que eu adicionei lá é definir o tipo de retorno do componente para React.StatelessComponenttipo.

Para um componente com seus próprios adereços personalizados (como MyPropsinterface):

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

Agora, propsobteve a childrenpropriedade, bem como as da MyPropsinterface.

Eu verifiquei isso na versão datilografada 2.0.7

Além disso, você pode usar em React.SFCvez de React.StatelessComponentpara abreviar.


Obrigado! Parece que estou em uma versão antiga das tipificações que não suportam isso ... Acho que é hora de morder a bala e usar TS 2.0 com@types
Aaron Beall

3
React.StatelessComponent/ React.SFCestão obsoletos. Em React.FunctionComponentvez disso, é recomendável consultar .
Alexander Kachkaev

Observe que este método não funciona se você tiver um componente genérico
FunkeyFlo

94

Você pode usar o React.PropsWithChildren<P>tipo para seus adereços:

interface MyProps { }

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

0

Você pode usar

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

React.SFCestá obsoleto
Arjan

0

Resposta mais simples: Use ReactNode:

interface MyProps {
  children?: React.ReactNode
}

Se childrené opcional ou não (ou seja, ter ?ou não) depende do seu componente. Essa ?é a maneira mais concisa de expressar isso, então nada de errado com isso.

No histórico: esta não era necessariamente a resposta correta quando perguntado originalmente: o tipo ReactNodefoi adicionado em (quase) sua forma atual em março de 2017 apenas por esta solicitação de pull , mas quase todos que estão lendo isso hoje devem estar em uma versão moderna do React .

Por último, sobre passar childrencomo "atributo" (que, no jargão do React, seria passar como "prop", não atributo): É possível, mas na maioria dos casos é melhor ler ao passar filhos JSX:

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

lê mais facilmente do que

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

0

Você pode apenas adicionar filhos ao componente e se ele estiver conectado a um contêiner, isso é tudo que você precisa.

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

}

Por que adicionar outra resposta a uma pergunta tão antiga?
Mike Szyndel

E era uma pergunta do TypeScript.
Zsolt Meszaros
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.