React: Perguntas sobre "props.children"

Criado em 26 mai. 2018  ·  6Comentários  ·  Fonte: facebook/react

Você quer solicitar um recurso ou relatar um bug ?
Apenas perguntas

Algumas perguntas sobre props.children

Na documentação oficial do React do React.Children você pode ler que this.props.children é uma "estrutura de dados opaca".
O que isso significa EXATAMENTE?

Acho que existem, em geral, três possibilidades para a transparência da estrutura de dados de props.children :

Caso 1: TODOS os aspectos da estrutura de dados props.children são abertos e bem definidos.

Se isso estivesse certo, o termo "estrutura de dados opaca" estaria completamente errado.
Portanto, o "Caso 1" obviamente não é o caso.

Caso 2: NENHUM aspecto da estrutura de dados props.children está aberto ou limpo.

Isso significa que sempre que você usar props.children você SEMPRE PRECISA usá-lo em combinação com React.Children pois React.Children é o único (mmmh, é realmente o único?) quem sabe sobre a estrutura de dados real de props.children .

Mas isso implicaria que não deveria ser permitido usar

javascript // This is used almost everywhere (even in the official React documentation) <div>{this.props.children}</div>

nem

javascript // This is often seen with the "Function as child" pattern MyComponent.propTypes = { children: PropTypes.func.isRequired, };

Como os dois exemplos são muito comuns, parece que o "Caso 2" obviamente também não é o caso.

Caso 3: ALGUNS aspectos da estrutura de dados props.children estão abertos e bem definidos.

Isso abriria a possibilidade de que um ou mesmo ambos os exemplos no "Caso 2" sejam válidos.
Mas então isso significaria que deveria haver uma especificação exata de quais aspectos de props.children estão bem e abertamente definidos e quais aspectos são realmente opacos.
Talvez eu tenha esquecido algo na documentação do React, mas acho que não está exatamente especificado lá, está?

E por último, mas não menos importante, uma outra questão:

Por que exatamente props.children não é no caso de haver alguns filhos (um ou mais) apenas sempre um array (como é feito em "Preact" por exemplo)? Isso tornaria as coisas muito mais fáceis, não é?

Muito obrigado desde já pelos esclarecimentos.

Question

Comentários muito úteis

_Estrutura de dados opaca_ refere-se ao fato de que children pode ser muitas coisas: matrizes, fragmentos, elementos únicos, literais de string, etc.

_React.Children_ contém alguns métodos que permitem que você trabalhe com os diferentes tipos de children _de uma forma unificada_, e definitivamente não é a única maneira de interagir com eles.

Por que exatamente props.children no caso de haver alguns filhos (um ou mais) apenas sempre um array (como é feito em "Preact" por exemplo)?

Além do fato de ter uma abreviação em JSX, children é uma propriedade como qualquer outra. Na verdade, você pode especificá-lo como:

<Component children={...}/>

Quando o React precisa atualizar o DOM, seria muito mais caro dizer se duas matrizes de item único são iguais do que se dois valores primitivos (por exemplo, strings) são iguais.

Dito isso, acho que a documentação do React.Children pode ser um pouco expandida, mas isso é um problema para registrar no repositório reactjs / reactjs.org .

Este artigo pode esclarecer um pouco as coisas, ele fez por mim!

Todos 6 comentários

_Estrutura de dados opaca_ refere-se ao fato de que children pode ser muitas coisas: matrizes, fragmentos, elementos únicos, literais de string, etc.

_React.Children_ contém alguns métodos que permitem que você trabalhe com os diferentes tipos de children _de uma forma unificada_, e definitivamente não é a única maneira de interagir com eles.

Por que exatamente props.children no caso de haver alguns filhos (um ou mais) apenas sempre um array (como é feito em "Preact" por exemplo)?

Além do fato de ter uma abreviação em JSX, children é uma propriedade como qualquer outra. Na verdade, você pode especificá-lo como:

<Component children={...}/>

Quando o React precisa atualizar o DOM, seria muito mais caro dizer se duas matrizes de item único são iguais do que se dois valores primitivos (por exemplo, strings) são iguais.

Dito isso, acho que a documentação do React.Children pode ser um pouco expandida, mas isso é um problema para registrar no repositório reactjs / reactjs.org .

Este artigo pode esclarecer um pouco as coisas, ele fez por mim!

Muito obrigado @danburzo por suas respostas e esclarecimentos.
Depois de sua resposta, está claro que não entendi completamente a palavra "opaco" aqui.
A documentação do React queria apenas dizer que a estrutura de dados de props.children é um tipo de união completamente bem definido e que varia em sua representação concreta (como os tipos de união sempre fazem).

Acabei de encontrar um problema antigo que abordava exatamente o mesmo tópico - me pergunto o que aconteceu com essas mudanças?!? (Eu abri um problema em reactjs.org => reactjs / reactjs.org # 914):

https://github.com/facebook/react/pull/6018/files/91223423410f107ff83a8a6ce3158c488247292f?short_path=ef51787#diff -ef51787305cfed62f6f564284762d4de

No entanto, ainda gostaria de fazer a segunda pergunta novamente:
Por que "props.children" NÃO é um array no caso de haver exatamente UM filho (realmente parece uma violação do princípio de menor espanto se você não conhece o fundo => se o nome é "filhos" ou "itens" ou "tokens" que você normalmente espera uma coleção)?
É realmente por motivos de desempenho? Eu realmente não consigo ver que o cálculo de "checkResult" abaixo é tão demorado:

const
  child1 = ...,
  child2 = ...,
  child1IsArray = Array.isArray(child1),
  child2IsArray = Array.isArray(child2),

  checkResult = child1IsArray && child2IsArray
     && child1.length === 1 && child2.length === 1
     && child1[0] === child2[0]; 

Desculpe se perguntar novamente parece um pouco chato - mas eu realmente adoraria saber o motivo exato para essa decisão de design ...

Estou feliz por ter ajudado com a primeira parte de sua pergunta! Infelizmente, quanto ao motivo pelo qual filhos únicos não são representados como uma matriz de item único, não tenho uma resposta _exata_. No entanto, eu estava tentando apontar que você ainda pode validamente passar uma única criança como um suporte normal (em vez da abreviação JSX), um fato que eu acidentalmente obscurei com minha hipótese de que está relacionado ao desempenho.

@danburzo Obrigado novamente por sua resposta.

Mmh, francamente, eu esperava que talvez alguém da equipe React se lembrasse do motivo real para essa decisão de design ...
Porque existem realmente alguns problemas sutis com o manuseio de objetos infantis no React.
Por exemplo, pergunte a um novato do React se os componentes Test1 e Test2 no exemplo a seguir se comportam da mesma forma (você - como um profissional do React - sabe que a resposta é "não" => Test2 avisará no DEV sobre as chaves ausentes enquanto Test1 irá não - mas isso é realmente o que você esperaria se fosse um novato?!?)

const
  h = React.createElement,
  Test1 = () => h('div', null, h('br'), h('br')),
  Test2 = () => h('div', { children: [h('br'), h('br')] });

ReactDOM.render(
  h('div', null, h(Test1), h(Test2)),
  document.getElementById('container')
);

A propósito: Se Test2 fosse permitido, isso teria alguns benefícios de desempenho sutis se você estiver implementando algumas substituições de createElement - como alguma função de hiperescrito, por exemplo.

Outro exemplo: pergunte a um novato do React como seria "children: PropTypes ...." se o requisito fosse que todos os filhos satisfaçam uma determinada condição. Acho que não seria fácil responder (pelo menos para um novato).

Para a equipe React: Se as razões para a decisão de design em questão não forem realmente conhecidas ou talvez apenas uma questão de gosto, então, é claro, fique à vontade para encerrar este problema.

Presumo que a decisão de não usar uma matriz para um único filho foi tomada para evitar alocações de matriz desnecessárias.

Porque existem realmente alguns problemas sutis com o manuseio de objetos infantis no React.

Geralmente não recomendamos o uso de um children prop explícito. A maioria dos usuários também usa JSX em vez de chamar diretamente React.createElement , portanto, os problemas que você mencionou normalmente não são um problema.

@aweary Obrigado pela sua resposta

Esta página foi útil?
0 / 5 - 0 avaliações