¿Cómo evitar un envoltorio adicional <div> en React?

113

Hoy comencé a aprender ReactJS y después de una hora enfrenté el problema ... Quiero insertar un componente que tiene dos filas dentro de un div en la página. Un ejemplo simplificado de lo que estoy haciendo a continuación.

Tengo un html:

<html>
..
  <div id="component-placeholder"></div>
..
</html>

Función de renderizado como esta:

...
render: function() {

    return(
        <div className="DeadSimpleComponent">
            <div className="DeadSimpleComponent__time">10:23:12</div >
            <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
        </div>
    )
}
....

Y debajo estoy llamando a render:

ReactDOM.render(<DeadSimpleComponent/>, document.getElementById('component-placeholder'));

El HTML generado se ve así:

<html>
..
  <div id="component-placeholder">
    <div class="DeadSimpleComponent">
            <div class="DeadSimpleComponent__time">10:23:12</div>
            <div class="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
    </div>
</div>
..
</html>

El problema es que no estoy muy contento de que React me obligue a envolver todo en un div "DeadSimpleComponent". ¿Cuál es la mejor y más sencilla solución, sin manipulaciones DOM explícitas?

ACTUALIZACIÓN 28/7/2017: Los mantenedores de React agregaron esa posibilidad en React 16 Beta 1

Desde React 16.2 , puede hacer esto:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}
Kirill Reznikov
fuente
4
práctica de nomenclatura perfecta ;-)
Kirill Reznikov
¿Puedo ver su archivo HTML? He leído mal tu pregunta. Sin embargo, puede que tenga una solución.
Louis93
Algo así: jsfiddle.net/qawumm3v
Kirill Reznikov
¿Tiene algún problema con un componente que tiene un solo elemento? De Verdad?
Domingo
¿Qué quieres decir? Solo estoy probando React, no debería ser muy complicado ... Pero la limitación parece molesta.
Kirill Reznikov

Respuestas:

142

Este requisito se eliminó en la versión React (16.0)] 1 , por lo que ahora puede evitar ese contenedor.

Puede usar React.Fragment para representar una lista de elementos sin crear un nodo principal, ejemplo oficial:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

Más aquí: Fragmentos

Luger
fuente
1
Buenas noticias DmitryUlyanets. ¿Hay alguna fecha de lanzamiento prevista?
Jonas Carlbaum
Se lanzó desde el 26 de septiembre de 2017, consulte reactjs.org/blog/2017/09/26/react-v16.0.html
Tom
56

Actualización 2017-12-05: React v16.2.0 ahora es totalmente compatible con la representación de fragmentos con soporte mejorado para devolver varios elementos secundarios de un método de representación de componentes sin especificar claves en los elementos secundarios:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

Si está utilizando una versión de React anterior a la v16.2.0, también es posible utilizar <React.Fragment>...</React.Fragment>en su lugar:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

Original:

React v16.0 introdujo devolver una matriz de elementos en el método de renderizado sin envolverlo en un div: https://reactjs.org/blog/2017/09/26/react-v16.0.html

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

Por el momento, se requiere una clave para cada elemento para evitar la advertencia de clave, pero esto podría cambiarse en versiones futuras:

En el futuro, es probable que agreguemos una sintaxis de fragmento especial a JSX que no requiere claves.

Tom
fuente
La nueva sintaxis abreviada de <> </> es excelente. Sin embargo, todavía tengo muchos sentimientos encontrados al respecto.
Thulani Chivandikwa
@ThulaniChivandikwa ¿Le importaría expresar sus dudas sobre la sintaxis taquigráfica?
Tom
1
Creo que se trata más del concepto de que una etiqueta vacía es extraña en JSX y no es muy intuitiva a menos que sepa exactamente lo que hace.
Thulani Chivandikwa
7

Puedes usar:

render(){
    return (
        <React.Fragment>
           <div>Some data</div>
           <div>Som other data</div>
        </React.Fragment>
    )
}

Para obtener más detalles, consulte esta documentación .

Rolando Cintrón
fuente
3

Utilice [], en lugar de () para envolver toda la devolución.

render: function() {
  return[
    <div className="DeadSimpleComponent__time">10:23:12</div >
    <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
  ]
}
Michael Cuneo
fuente
1

Esto todavía es necesario , PERO React ahora asegúrese de crear elementos sin crear un elemento DOM adicional.

La envoltura adicional necesaria (normalmente con un padre div) porque ReactscreateElement método requiere un typeparámetro que es either a tag name string (such as 'div' or 'span'), a React component type (a class or a function). Pero esto fue antes de que presentaran React Fragment.

Referir este NUEVO documento de api para createElement

React.createElement : crea y devuelve un nuevo elemento React del tipo dado. El argumento de tipo puede ser una cadena de nombre de etiqueta (como 'div' o 'span'), un tipo de componente React (una clase o una función), o un tipo de fragmento React .

aquí está el ejemplo oficial, Refer React.Fragment .

render() {
  return (
    <React.Fragment>
      Some text.
      <h2>A heading</h2>
    </React.Fragment>
  );
}
principal
fuente
0

No podrás deshacerte de ese divelemento. React.render () necesita devolver un nodo DOM válido.

Henrik Andersson
fuente
los div se ignoran, Knockout.JS hace lo mismo. tener un div sin estilo en la parte exterior de su componente no afecta nada.
Chris Hawkes
16
@ChrisHawkes, en desacuerdo. un div contenedor afecta a los selectores de CSS.
Downhillski
Cuando se trabaja con elementos semánticos, que no desea ser completamente componentes de React, esto se convierte en un problema. Digamos que hay una etiqueta de sección con elementos de encabezado y pie de página, y entre ellos hay un contenedor de mapas de Google, que no queremos usar dentro de React. Entonces sería bueno tener el encabezado como un componente de React y el pie de página como un componente de React, sin tener que incluir div: s adicionales afuera y adentro de los componentes de React ... Ese es un diseño simple y estúpido, si te importa el html salida ...
Jonas Carlbaum
0

A continuación, se muestra una forma de renderizar componentes "transculentos":

import React from 'react'

const Show = (props) => {
  if (props.if || false) {
    return (<React.Fragment>{props.children}</React.Fragment>)
  }
  return '';
};

----


<Show if={yomama.so.biq}>
    <img src="https://yomama.so.biq">
    <h3>Yoamama</h3>
<Show>

ingrese la descripción de la imagen aquí

Ярослав Рахматуллин
fuente
0

También hay una solución. El siguiente código de bloque genera un fragmento sin la necesidad de React.Fragment.

return [1,2,3].map(i=>{
if(i===1) return <div key={i}>First item</div>
if(i===2) return <div key={i}>Second item</div>
return <div key={i}>Third item</div>
})
erfan seidipoor
fuente
0

Sé que esta pregunta ha sido respondida, por supuesto, puede usar React.Fragment que no crea un nodo pero le permite agrupar cosas como un div.

Además, si quieres divertirte, puedes implementar (y aprender muchas cosas) un modo React que elimina los div extra y, para esto, realmente quiero compartir un gran video sobre cómo puedes hacerlo en la base del código de reacción.

https://www.youtube.com/watch?v=aS41Y_eyNrU

Por supuesto, esto no es algo que haría en la práctica, pero es una buena oportunidad de aprendizaje.

Gabriel P.
fuente