Comment éviter un wrapping supplémentaire <div> dans React?

114

Aujourd'hui, j'ai commencé à apprendre ReactJS et après une heure confronté au problème .. Je veux insérer un composant qui a deux lignes à l'intérieur d'un div sur la page. Un exemple simplifié de ce que je fais ci-dessous.

J'ai un html:

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

Fonction de rendu comme ceci:

...
render: function() {

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

Et ci-dessous, j'appelle render:

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

Le HTML généré ressemble à ceci:

<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>

Le problème que je ne suis pas très content que React m'oblige à tout envelopper dans un div "DeadSimpleComponent". Quelle est la meilleure solution de contournement simple pour cela, sans manipulations DOM explicites?

MISE À JOUR 28/07/2017: Les responsables de React ont ajouté cette possibilité dans React 16 Beta 1

Depuis React 16.2 , vous pouvez faire ceci:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}
Kirill Reznikov
la source
4
pratique de nommage parfaite ;-)
Kirill Reznikov
Puis-je voir votre fichier HTML? J'ai mal lu votre question. J'ai peut-être une solution de contournement.
Louis93
Smth comme ceci: jsfiddle.net/qawumm3v
Kirill Reznikov
Vous avez un problème avec un composant ayant un seul élément? Vraiment?
Dominic
Que voulez-vous dire? J'essaye juste React, ça ne devrait pas être très compliqué. Mais la limitation semble ennuyeuse.
Kirill Reznikov

Réponses:

142

Cette exigence a été supprimée dans la version React (16.0)] 1 , vous pouvez donc désormais éviter ce wrapper.

Vous pouvez utiliser React.Fragment pour afficher une liste d'éléments sans créer de nœud parent, exemple officiel:

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

Plus ici: Fragments

Luger
la source
1
Bonne nouvelle DmitryUlyanets. Y a-t-il une date de sortie prévue?
Jonas Carlbaum
Il est publié depuis le 26 septembre 2017, voir reactjs.org/blog/2017/09/26/react-v16.0.html
Tom
56

Mise à jour 05/12/2017: React v16.2.0 prend désormais entièrement en charge le rendu des fragments avec une prise en charge améliorée du retour de plusieurs enfants à partir d'une méthode de rendu de composants sans spécifier de clés dans les enfants:

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

Si vous utilisez une version de React antérieure à la v16.2.0, il est également possible d'utiliser à la <React.Fragment>...</React.Fragment>place:

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

Original:

React v16.0 a introduit le retour d'un tableau d'éléments dans la méthode de rendu sans l'envelopper dans 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>,
  ];
}

Pour le moment, une clé est requise pour chaque élément afin d'éviter l'avertissement de clé, mais cela pourrait être modifié dans les versions futures:

À l'avenir, nous ajouterons probablement une syntaxe de fragment spéciale à JSX qui ne nécessite pas de clés.

À M
la source
La nouvelle syntaxe abrégée de <> </> est excellente. Cependant, j'ai encore beaucoup de sentiments mitigés à ce sujet.
Thulani Chivandikwa
@ThulaniChivandikwa Pourriez-vous exprimer vos doutes sur la syntaxe sténographique?
Tom le
1
Je pense qu'il s'agit davantage du concept d'une balise vide étant étrange dans le JSX et pas très intuitive à moins que vous ne sachiez exactement ce qu'elle fait.
Thulani Chivandikwa
7

Vous pouvez utiliser:

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

Pour plus de détails, reportez-vous à cette documentation .

Rolando Cintron
la source
3

Utilisez [] au lieu de () pour encapsuler le retour entier.

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

Ceci est toujours nécessaire , MAIS React assurez-vous maintenant de créer des éléments sans créer d'élément DOM supplémentaire.

L'emballage supplémentaire nécessaire (normalement avec un parent div) car la createElementméthode Reacts nécessite un typeparamètre qui est either a tag name string (such as 'div' or 'span'), a React component type (a class or a function). Mais c'était avant l'introduction de React Fragment.

Référez - vous à ce NOUVEAU doc api pour createElement

React.createElement : crée et renvoie un nouvel élément React du type donné. L'argument type peut être une chaîne de nom de balise (telle que «div» ou «span»), un type de composant React (une classe ou une fonction) ou un type de fragment React .

voici l'exemple officiel, Refer React.Fragment .

render() {
  return (
    <React.Fragment>
      Some text.
      <h2>A heading</h2>
    </React.Fragment>
  );
}
premier
la source
0

Vous ne pourrez pas vous débarrasser de cet divélément. React.render () doit renvoyer un nœud DOM valide.

Henrik Andersson
la source
les div sont ignorés, Knockout.JS fait la même chose. avoir un div sans style sur la partie extérieure de votre composant n'a aucun effet.
Chris Hawkes
16
@ChrisHawkes, pas d'accord. un div wrapper affecte les sélecteurs css.
Downhillski
Lorsque vous travaillez avec des éléments sémantiques, que vous ne voulez pas être entièrement des composants React, cela devient un problème. Disons qu'il y a une section-tag avec des éléments d'en-tête et de pied de page, et entre eux il y a un google map-container, que nous ne voulons pas utiliser dans React. Ensuite, il serait bien d'avoir un en-tête en tant que composant React et un pied de page en tant que composant React, sans avoir à inclure des div supplémentaires: s à l'extérieur à l'intérieur des composants React ... C'est une conception stupide, si vous vous souciez du html you output ...
Jonas Carlbaum
0

Voici une façon de rendre les composants "transculents":

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>

entrez la description de l'image ici

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

Il existe également une solution de contournement. Le code de bloc ci-dessous génère un fragment sans avoir besoin 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
la source
0

Je sais que cette question a été répondue, vous pouvez bien sûr utiliser React.Fragment qui ne crée pas de nœud mais vous permet de regrouper des éléments comme un div.

De plus, si vous voulez vous amuser, vous pouvez implémenter (et apprendre beaucoup de choses) un mode React qui supprime les div supplémentaires et pour cela, je veux vraiment partager une excellente vidéo sur la façon dont vous pouvez le faire sur la base de code de réaction elle-même.

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

Ce n'est bien sûr pas quelque chose que vous feriez dans la pratique, mais c'est une bonne opportunité d'apprentissage.

Gabriel P.
la source