Warum sind Fragmente in Reaktion 16 besser als Container-Divs?

164

In React 16.2 wurde eine verbesserte Unterstützung für Fragmentshinzugefügt. Weitere Informationen finden Sie in Reacts Blogbeitrag hier.

Wir alle kennen den folgenden Code:

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

Ja, wir brauchen ein Container-Div, aber es ist keine so große Sache.

In React 16.2 können wir dies tun, um das umgebende Container-Div zu vermeiden:

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

In beiden Fällen benötigen wir noch ein Containerelement, das die inneren Elemente umgibt.

Meine Frage ist, warum ist eine Fragmentvorzuziehen? Hilft es bei der Leistung? Wenn ja warum? Würde gerne einen Einblick bekommen.

Max Millington
quelle
2
Ich finde es wirklich nützlich für das Flexbox-Styling, wenn ich Kinder der ersten Stufe für einen Elternteil
erstelle
32
Das Problem dabei divist, dass Sie nicht immer ein Wrapper-Element möchten. Wrapper-Elemente haben eine Bedeutung, und normalerweise benötigen Sie zusätzliche Stile, damit diese Bedeutung entfernt wird. <Fragment>ist nur syntaktischer Zucker, der nicht gerendert wird. Es gibt Situationen, in denen das Erstellen eines Wrappers sehr schwierig ist, z. B. in SVG, wo <div>es nicht verwendet werden kann und <group>nicht immer das ist, was Sie wollen.
Sulthan

Antworten:

304
  1. Es ist ein kleines bisschen schneller und hat weniger Speicherbedarf (es muss kein zusätzlicher DOM-Knoten erstellt werden). Dies hat nur bei sehr großen und / oder tiefen Bäumen einen echten Vorteil, aber die Anwendungsleistung leidet häufig unter dem Tod durch tausend Schnitte. Dies ist ein Schnitt weniger.
  2. Einige CSS-Mechanismen wie Flexbox und CSS Grid haben eine spezielle Eltern-Kind-Beziehung, und das Hinzufügen von divs in der Mitte macht es schwierig, das gewünschte Layout beizubehalten, während logische Komponenten extrahiert werden.
  3. Der DOM-Inspektor ist weniger überladen. :-)

Die Beschreibungen einiger anderer Anwendungsfälle finden Sie in diesem React-Problem: Fügen Sie eine Fragment-API hinzu, um die Rückgabe mehrerer Komponenten aus dem Rendering zu ermöglichen

Dan Abramov
quelle
24
4. Das Schreiben von Definitionslisten wird <dt><dd>viel einfacher. Die Rückgabe gepaarter Elemente war zuvor umständlich Fragments.
Sonson123
Arbeiten Fragmente in reaktionsnativen? Ich habe es versucht import Fragment from 'react'. Aber es ist in RN undefiniert.
Binchik
3
Denn number 2Tische waren für uns das größte Problem. Die benötigte Struktur von table>tr>td(möglicherweise mit theadund ähnlich) sorgte für einen umständlichen React-Code.
Matsemann
2
@ Binchik versucht import {Fragment} from 'react'? Es ist ein benannter Export.
Soska
1
Nummer 3 ist das Wichtigste!
Zach Smith
28

Zu allen obigen Antworten gibt es noch einen weiteren Vorteil: Code-Lesbarkeit , FragmentKomponente unterstützt eine syntaktische Zuckerform , <>. Somit kann der Code in Ihrer Frage einfacher geschrieben werden als:

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

Laut docs ,

In React wird dies zu einem <React.Fragment/>Element, wie im Beispiel aus dem vorherigen Abschnitt. (Non-React-Frameworks, die JSX verwenden, werden möglicherweise zu etwas anderem kompiliert.)

Unordnungfrei, oder?

Beachten Sie, dass Sie weiterhin die <Fragment>Syntax verwenden müssen, wenn Sie keydas Fragment bereitstellen möchten.

Däne
quelle
Diese kürzere Syntax wird derzeit in der Create-React-App noch nicht unterstützt. Siehe: reactjs.org/docs/fragments.html#short-syntax
codingsplash
2
@codingsplash CRA 2.0 hat es jetzt.
Treffen Sie Zaveri
1
Ich kann dieses Stück syntaktischen Zuckers nicht ausstehen, es sieht unbeabsichtigt aus und vermittelt wenig inhärente Bedeutung. Viel lieber<Fragment>
ESR
3
@ ESR persönlich gefällt es mir. Denk darüber so. Die Kinder sind in nichts eingewickelt, genauso wie es nichts im <> gibt. Unsichtbar.
user3614030
6
  • Zusätzliche Funktionen, die zuvor mit JSX nicht möglich waren
  • Besseres semantisches JSX-Markup. Wrapper-Elemente werden bei Bedarf verwendet, nicht weil sie dazu gezwungen werden.
  • Weniger Dom-Markup insgesamt (höhere Renderleistung und weniger Speicheraufwand)

So einfach wie wenn Sie kein Wrapper-Element benötigen, müssen Sie keines verwenden. Weniger Elemente zu haben ist großartig, aber ich denke, der größte Vorteil besteht darin, Elemente in jsx rendern zu können, die vorher nicht möglich waren, und Wrapper-Elementen eine bessere semantische Bedeutung zu verleihen, da sie jetzt optional sind.

Das war vorher nicht möglich:

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

Wenn Sie in Reaktion 15 auf Folgendes schauen, können Sie nicht feststellen, ob das Wrapper-Element benötigt wird oder nicht:

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

Gemäß den Dokumenten von reactjs.org besteht die wichtigste Anforderung <Fragment> </Fragment>anstelle von div darin, zu vermeiden, dass die HTML-Semantik unterbrochen wird. Wenn wir divs anstelle von verwenden <Fragment> </Fragment>, brechen wir die HTML-Semantik.

Um mehr über die HTML-Semantik zu erfahren. Bitte klicken Sie und es gibt auch Fälle, in denen wenn Sie divs anstelle von Fragmenten verwenden, diese ungültig sind. Sehen Sie sich beispielsweise diesen Code an:

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>

Fragmente lösen dieses Problem.

Seeta Ram Yadav
quelle
1
  1. Mit <React.Fragment>...</React.Fragment>können wir unseren JSX-Elementen ein übergeordnetes Tag hinzufügen, ohne dem DOM einen zusätzlichen Knoten hinzuzufügen.
  2. Sie können die zusätzlichen div-Tags durch React.Fragment ersetzen
  3. Das Schreiben von React.Fragment ist jedes Mal zu lang für Sie. React.Fragment verfügt über eine Kurzsyntax, die Sie verwenden können. Es ist<>...</>.
Hemant
quelle