Por que os fragmentos no React 16 são melhores que os divs do contêiner?

165

No React 16.2, Fragmentsfoi adicionado suporte aprimorado para . Mais informações podem ser encontradas no post do React aqui.

Todos conhecemos o seguinte código:

render() {
  return (
    // Extraneous div element :(
    <div>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </div>
  );
}

Sim, precisamos de uma div de contêiner, mas não é grande coisa.

No React 16.2, podemos fazer isso para evitar a div do contêiner ao redor:

render() {
  return (
    <Fragment>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </Fragment>
  );
}

Nos dois casos, ainda precisamos de um elemento contêiner cercando os elementos internos.

Minha pergunta é: por que usar um Fragmentpreferível? Isso ajuda com o desempenho? Se sim, por quê? Amaria alguma introspecção.

Max Millington
fonte
2
Acho que é realmente útil para o estilo flexbox ao criar filhos de primeiro nível para pais
willwoo
32
O problema divé que nem sempre você deseja um elemento wrapper. Os elementos do wrapper têm um significado e geralmente você precisa de estilos adicionais para que esse significado seja removido. <Fragment>é apenas açúcar sintático que não é processado. Há situações em que a criação de um wrapper é muito difícil, por exemplo, no SVG, onde <div>não pode ser usado e <group>nem sempre é o que você deseja.
precisa

Respostas:

305
  1. É um pouco mais rápido e possui menos uso de memória (não é necessário criar um nó DOM extra). Isso só tem um benefício real em árvores muito grandes e / ou profundas, mas o desempenho do aplicativo geralmente sofre com a morte por mil cortes. Este é um corte a menos.
  2. Alguns mecanismos CSS, como o Flexbox e o CSS Grid, têm um relacionamento pai-filho especial, e adicionar divs no meio dificulta a manutenção do layout desejado ao extrair componentes lógicos.
  3. O inspetor DOM está menos confuso. :-)

Você pode encontrar as descrições de alguns outros casos de uso neste problema do React: Adicione API de fragmento para permitir o retorno de vários componentes da renderização

Dan Abramov
fonte
24
4. Escrever listas de definições <dt><dd>fica muito mais fácil. Retornar elementos emparelhados era estranho antes Fragments.
Sonson123
Os fragmentos funcionam em reação nativa? Eu tentei import Fragment from 'react'. Mas é indefinido no RN.
binchik
3
Pois number 2, as mesas têm sido o maior problema para nós. A estrutura necessária table>tr>td(possivelmente com theade similar) resultou em algum código React estranho.
Matsemann
2
@binchik tentou import {Fragment} from 'react'? é uma exportação nomeada.
Soska
1
O número 3 é o mais importante!
Zach Smith #
28

Adicionando a todas as respostas acima, há mais uma vantagem: legibilidade do código , o Fragmentcomponente suporta uma forma sintática de açúcar <>,. Assim, o código na sua pergunta pode ser escrito mais facilmente como:

render() {
  return (
    <>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </>
  );
}

De acordo com documentos ,

Em React, isso desugura para um <React.Fragment/>elemento, como no exemplo da seção anterior. (Estruturas sem reação que usam JSX podem ser compiladas para algo diferente.)

Livre de desordem, certo?

Observe que você ainda precisará usar a <Fragment>sintaxe se precisar fornecer keyao fragmento.

dinamarquês
fonte
No momento, essa sintaxe mais curta ainda não é suportada no create-react-app. Consulte: reactjs.org/docs/fragments.html#short-syntax
codingsplash
2
@codingsplash CRA 2.0 tem agora.
Conheça Zaveri
1
Não aguenta esse pedaço de açúcar sintático, parece não intencional e transmite pouco significado inerente. Muito preferem<Fragment>
ESR
3
@ESR pessoalmente, eu gosto. Pense desta maneira. As crianças estão envolvidas em nada, assim como não há nada no <>. Invisível.
User3614030
6
  • Recursos adicionados não possíveis antes com JSX
  • Melhor marcação jsx semântica. Os elementos do invólucro são usados ​​quando necessário, não porque são forçados.
  • Menos marcação geral do Dom (desempenho aprimorado de renderização e menos sobrecarga de memória)

Tão simples quanto quando você não precisa de um elemento wrapper, não é obrigado a usá-lo. Ter menos elementos é ótimo, mas acho que o maior benefício é poder renderizar elementos em jsx que não eram possíveis anteriormente e adicionar melhor significado semântico aos elementos do wrapper, porque agora são opcionais.

Isso não era possível antes:

 <select>
    {this.renderOptions()}
 </select>

Olhando para o seguinte no React 15, você não pode dizer se o elemento wrapper é necessário ou não:

<span>
  <h1>Hello</h1>
  {this.getContent()}
</span>
reclamar
fonte
2

De acordo com os documentos do reactjs.org, as necessidades mais importantes, em <Fragment> </Fragment>vez das divs , são evitar a quebra da semântica do HTML. Quando usamos div em vez de <Fragment> </Fragment>quebrar a semântica do HTML.

Para saber mais sobre semântica html. por favor clique e também há casos em que se usam div é em vez de fragmentos Será html inválido, por exemplo olhada neste código:

class Columns extends React.Component {
  render() {
    return (
      <div>
        <td>Hello</td>
        <td>World</td>
      </div>
    );
  }
}

<table>
      <tr>
        <div>
          <td>Hello</td>
          <td>World</td>
        </div>
      </tr>
 </table>

Fragmentos resolvem esse problema.

Seeta Ram Yadav
fonte
1
  1. Usando <React.Fragment>...</React.Fragment>, podemos adicionar uma tag pai aos nossos elementos JSX sem adicionar um nó extra ao DOM.
  2. você pode substituir as tags div extras por React.Fragment
  3. escrever React.Fragment sempre é muito longo para você. React.Fragment possui uma sintaxe abreviada que você pode usar. Isto é<>...</>.
Hemant
fonte