Dlaczego fragmenty w React 16 są lepsze niż elementy div kontenera?

165

W Reakcie 16.2 Fragmentsdodano ulepszone wsparcie dla . Więcej informacji można znaleźć w poście na blogu Reacta tutaj.

Wszyscy znamy następujący kod:

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

Tak, potrzebujemy kontenera div, ale to nic wielkiego.

W Reakcie 16.2 możemy to zrobić, aby uniknąć otaczającego kontenera div:

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

W obu przypadkach nadal potrzebujemy elementu kontenera otaczającego elementy wewnętrzne.

Moje pytanie brzmi: dlaczego używa się Fragmentpreferowanego? Czy to pomaga w wydajności? Jeśli tak, dlaczego? Chciałbym trochę wglądu.

Max Millington
źródło
2
Uważam, że jest to bardzo przydatne do stylizacji flexbox podczas tworzenia dzieci pierwszego poziomu dla rodzica
willwoo
32
Problem divpolega na tym, że nie zawsze chcesz mieć element opakowujący. Elementy opakowania mają znaczenie i zwykle potrzebujesz dodatkowych stylów, aby to znaczenie zostało usunięte. <Fragment>to tylko cukier syntaktyczny, który nie jest renderowany. Są sytuacje, w których tworzenie opakowania jest bardzo trudne, na przykład w SVG, gdzie <div>nie można go użyć i <group>nie zawsze jest to, czego chcesz.
Sulthan

Odpowiedzi:

305
  1. Jest trochę szybszy i zużywa mniej pamięci (nie ma potrzeby tworzenia dodatkowego węzła DOM). Przynosi to rzeczywistą korzyść tylko w przypadku bardzo dużych i / lub głębokich drzew, ale wydajność aplikacji często spada w wyniku tysiąca cięć. To jedno cięcie mniej.
  2. Niektóre mechanizmy CSS, takie jak Flexbox i CSS Grid, mają specjalną relację rodzic-dziecko, a dodanie divs w środku utrudnia zachowanie pożądanego układu podczas wyodrębniania komponentów logicznych.
  3. Inspektor DOM jest mniej zagracony. :-)

Opisy innych przypadków użycia można znaleźć w tym wydaniu React: Dodaj fragment API, aby umożliwić zwracanie wielu komponentów z renderowania

Dan Abramov
źródło
24
4. Pisanie list definicji <dt><dd>staje się dużo łatwiejsze. Wcześniej zwracanie sparowanych elementów było niewygodne Fragments.
Sonson123
Czy fragmenty działają w natywnym reagowaniu? Próbowałem import Fragment from 'react'. Ale to jest niezdefiniowane w RN.
binchik
3
Bo właśnie number 2stoły były dla nas największym problemem. Potrzebna struktura table>tr>td(prawdopodobnie z theadi podobna) została stworzona dla jakiegoś niezręcznego kodu React.
Matsemann
2
@binchik próbował import {Fragment} from 'react'? to nazwany eksport.
Soska
1
Numer 3 jest najważniejszy!
Zach Smith
28

Dodając do wszystkich odpowiedzi powyżej jest jeszcze jedna zaleta: Kod czytelność , Fragmentpodpory składnik a składniowym formą cukru <>. W ten sposób kod w twoim pytaniu można łatwiej napisać jako:

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

Zgodnie z docs ,

W Reakcie powoduje to zanik cukru na <React.Fragment/>element, jak w przykładzie z poprzedniej sekcji. (Struktury Non-React, które używają JSX, mogą kompilować się do czegoś innego).

Bez bałaganu, prawda?

Zwróć uwagę, że nadal musisz używać <Fragment>składni, jeśli chcesz podać keyfragment.

Duńczyk
źródło
Ta krótsza składnia nie jest obecnie obsługiwana w aplikacji create-react-app. Zobacz: Reactjs.org/docs/fragments.html#short-syntax
codingsplash
2
@codingsplash CRA 2.0 ma to teraz.
Spotkaj się z Zaveri
1
Nie mogę znieść tego kawałka cukru syntaktycznego, wygląda niezamierzenie i nie ma żadnego nieodłącznego znaczenia. Dużo wolę<Fragment>
ESR
3
@ESR osobiście mi się podoba. Pomyśl o tym w ten sposób. Dzieci są niczym zawinięte, tak jak nie ma nic w <>. Niewidzialny.
user3614030
6
  • Dodane funkcje, które wcześniej nie były możliwe w JSX
  • Lepsze semantyczne znaczniki JSX. Elementy opakowania są używane, gdy są potrzebne, a nie dlatego, że są do tego zmuszone.
  • Mniej ogólnych znaczników DOM (zwiększona wydajność renderowania i mniejsze obciążenie pamięci)

To tak proste, jak gdy nie potrzebujesz elementu opakowującego, nie musisz go używać. Posiadanie mniejszej liczby elementów jest świetne, ale myślę, że największą zaletą jest możliwość renderowania elementów w jsx, które wcześniej nie były możliwe, i nadanie lepszego znaczenia semantycznego elementom opakowującym, ponieważ są one teraz opcjonalne.

Wcześniej nie było to możliwe:

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

Patrząc na poniższe w Reakcie 15, nie możesz stwierdzić, czy element opakowania jest potrzebny, czy nie:

<span>
  <h1>Hello</h1>
  {this.getContent()}
</span>
pllee
źródło
2

Zgodnie z dokumentacją actjs.org, najważniejszymi potrzebami <Fragment> </Fragment>zamiast elementów div są unikanie łamania semantyki HTML. Kiedy używamy div zamiast <Fragment> </Fragment>, łamiemy semantykę HTML.

Aby dowiedzieć się więcej na temat semantyki HTML. proszę kliknąć, a są też przypadki, w których jeśli użyjesz div zamiast Fragments, będzie to nieprawidłowy html, na przykład spójrz na ten kod:

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>

Fragmenty rozwiązują ten problem.

Seeta Ram Yadav
źródło
1
  1. Używając <React.Fragment>...</React.Fragment>, możemy dodać tag nadrzędny do naszych elementów JSX bez dodawania dodatkowego węzła do DOM.
  2. możesz zastąpić dodatkowe znaczniki DIV React.Fragment
  3. pisanie React.Fragment za każdym razem jest dla Ciebie za długie. React.Fragment ma skróconą składnię, której możesz użyć. To jest<>...</>.
Hemant
źródło