¿Por qué los fragmentos en React 16 son mejores que los contenedores div?


165

En React 16.2, Fragmentsse agregó soporte mejorado para . Puede encontrar más información en la publicación del blog de React aquí.

Todos estamos familiarizados con el siguiente código:

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

Sí, necesitamos un contenedor div, pero no es tan importante.

En React 16.2, podemos hacer esto para evitar el contenedor circundante div:

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

En cualquier caso, aún necesitamos un elemento contenedor alrededor de los elementos internos.

Mi pregunta es, ¿por qué es Fragmentpreferible usar un ? ¿Ayuda con el rendimiento? Si es así, ¿por qué? Me encantaría alguna idea.


2
Me resulta realmente útil para el peinado FlexBox al crear los primeros niños de nivel para un padre
willwoo

32
El problema dives que no siempre quieres un elemento contenedor. Los elementos de envoltura tienen un significado y, por lo general, necesita estilos adicionales para eliminar ese significado. <Fragment>es solo azúcar sintáctico que no se procesa. Hay situaciones en las que crear un contenedor es muy difícil, por ejemplo, en SVG donde <div>no se puede usar y <group>no siempre es lo que desea.
Sulthan

Respuestas:


305
  1. Es un poco más rápido y tiene menos uso de memoria (no es necesario crear un nodo DOM adicional). Esto solo tiene un beneficio real en árboles muy grandes y / o profundos, pero el rendimiento de la aplicación a menudo sufre la muerte por mil cortes. Este es un corte menos.
  2. Algunos mecanismos CSS como Flexbox y CSS Grid tienen una relación padre-hijo especial, y agregar divs en el medio hace que sea difícil mantener el diseño deseado mientras se extraen los componentes lógicos.
  3. El inspector DOM está menos desordenado. :-)

Puede encontrar las descripciones de algunos otros casos de uso en este problema de React: agregue un fragmento de API para permitir la devolución de múltiples componentes del render


24
4. Escribir listas de definiciones se vuelve <dt><dd>mucho más fácil. Devolver elementos emparejados era incómodo antes Fragments.
Sonson123

¿Los fragmentos funcionan en react-native? Intenté import Fragment from 'react'. Pero no está definido en RN.
binchik

3
Para number 2, las tablas han sido en realidad el mayor problema para nosotros. La estructura necesaria de table>tr>td(posiblemente con theady similar) creó un código de reacción incómodo.
Matsemann

2
@binchik intentó import {Fragment} from 'react'? Es una exportación con nombre.
Soska

1
¡El número 3 es el más importante!
Zach Smith

28

Agregando a todas las respuestas arriba hay una ventaja más: la legibilidad del código , Fragmentsoportes de componentes una forma de azúcar sintáctica, <>. Por lo tanto, el código en su pregunta se puede escribir más fácilmente como:

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

Según los documentos ,

En React, esto se desugará a un <React.Fragment/>elemento, como en el ejemplo de la sección anterior. (Los frameworks que no son React que usan JSX pueden compilarse en algo diferente).

Libre de desorden, ¿verdad?

Tenga en cuenta que aún necesita usar la <Fragment>sintaxis si necesita proporcionar keyel fragmento.


Actualmente, esta sintaxis más corta aún no se admite en create-react-app. Consulte: reactjs.org/docs/fragments.html#short-syntax
codingsplash

2
@codingsplash CRA 2.0 lo tiene ahora.
Conoce a Zaveri el

1
No soporta esta pieza de azúcar sintáctica, parece involuntaria y transmite poco significado inherente. Mucho prefiero<Fragment>
ESR

3
@ESR personalmente me gusta. Piénsalo de esta manera. Los niños están envueltos en nada, al igual que no hay nada en el <>. Invisible.
user3614030

6
  • Funciones adicionales que antes no eran posibles con JSX
  • Mejor marcado semántico jsx. Los elementos de envoltura se usan cuando se necesitan, no porque estén forzados a hacerlo.
  • Menos marcado general de dom (mayor rendimiento de renderizado y menos sobrecarga de memoria)

Es tan simple como cuando no necesita un elemento envoltorio y no está obligado a usar uno. Tener menos elementos es excelente, pero creo que el mayor beneficio es poder representar elementos en jsx que antes no eran posibles y agregar un mejor significado semántico a los elementos envolventes porque ahora son opcionales.

Esto no era posible antes:

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

Echando un vistazo a lo siguiente en React 15, no puede saber si el elemento contenedor es necesario o no:

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

2

Según los documentos de reactjs.org, las necesidades más importantes en <Fragment> </Fragment>lugar de div son evitar romper la semántica HTML. Cuando usamos div's en lugar de<Fragment> </Fragment> romper la semántica HTML.

Para saber más sobre semántica html. Por favor, haga clic y también hay casos en que si se utiliza la div en lugar de fragmentos que será HTML no válido, por ejemplo vistazo a este 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>

Los fragmentos resuelven este problema.


1
  1. Utilizando <React.Fragment>...</React.Fragment> , podemos agregar una etiqueta principal a nuestros elementos JSX sin agregar un nodo adicional al DOM.
  2. puede reemplazar las etiquetas div adicionales con React.Fragment
  3. escribir React.Fragment cada vez es demasiado largo para ti. React.Fragment tiene una sintaxis abreviada que puedes usar. Es<>...</>.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.