Mengapa Fragmen dalam React 16 lebih baik daripada div kontainer?


165

Dalam Bereaksi 16.2, dukungan yang ditingkatkan untuk Fragmentstelah ditambahkan. Informasi lebih lanjut dapat ditemukan di posting blog React di sini.

Kita semua akrab dengan kode berikut:

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

Ya, kami membutuhkan div kontainer, tapi itu bukan masalah besar.

Dalam Bereaksi 16.2, kita bisa melakukan ini untuk menghindari div kontainer di sekitarnya:

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

Dalam kedua kasus tersebut, kita masih membutuhkan elemen penampung yang mengelilingi elemen dalam.

Pertanyaan saya adalah, mengapa menggunakan yang Fragmentlebih disukai? Apakah itu membantu kinerja? Jika demikian, mengapa? Akan menyukai wawasan.


2
Saya merasa sangat berguna untuk penataan flexbox saat membuat anak-anak tingkat pertama untuk orang tua
willwoo

32
Masalahnya divadalah Anda tidak selalu menginginkan elemen pembungkus. Elemen pembungkus memiliki arti dan biasanya Anda perlu gaya tambahan untuk menghapus makna itu. <Fragment>hanyalah gula sintaksis yang tidak dirender. Ada situasi ketika membuat pembungkus sangat sulit, misalnya dalam SVG di mana <div>tidak dapat digunakan dan <group>tidak selalu seperti yang Anda inginkan.
Sulthan

Jawaban:


305
  1. Ini sedikit lebih cepat dan memiliki lebih sedikit penggunaan memori (tidak perlu membuat simpul DOM tambahan). Ini hanya memiliki manfaat nyata pada pohon yang sangat besar dan / atau dalam, tetapi kinerja aplikasi sering menderita kematian dengan seribu tebasan. Ini satu potong lebih sedikit.
  2. Beberapa mekanisme CSS seperti Flexbox dan CSS Grid memiliki hubungan orangtua-anak yang khusus, dan menambahkan divs di tengah membuatnya sulit untuk mempertahankan tata letak yang diinginkan saat mengekstraksi komponen logis.
  3. Inspektur DOM tidak berantakan. :-)

Anda dapat menemukan deskripsi beberapa kasus penggunaan lain dalam masalah Bereaksi ini: Tambahkan API fragmen untuk memungkinkan pengembalian beberapa komponen dari render


24
4. Menulis daftar definisi <dt><dd>menjadi jauh lebih mudah. Mengembalikan elemen yang berpasangan terasa canggung sebelumnya Fragments.
Sonson123

Apakah Fragmen berfungsi dalam reaksi asli? Saya mencoba import Fragment from 'react'. Tapi itu tidak terdefinisi dalam RN.
binchik

3
Karena number 2, tabel sebenarnya merupakan masalah terbesar bagi kami. Struktur yang diperlukan table>tr>td(mungkin dengan theaddan serupa) dibuat untuk beberapa kode Reaksi canggung.
Matsemann

2
@binchik mencoba import {Fragment} from 'react'? ini bernama ekspor.
Soska

1
Nomor 3 adalah yang paling penting!
Zach Smith

28

Menambah semua jawaban di atas ada satu keuntungan lagi: keterbacaan kode , Fragmentkomponen mendukung bentuk gula sintaksis <>,. Dengan demikian kode dalam pertanyaan Anda dapat ditulis lebih mudah sebagai:

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

Menurut dokumen ,

Di Bereaksi, ini keinginan untuk <React.Fragment/>elemen, seperti pada contoh dari bagian sebelumnya. (Kerangka kerja Non-React yang menggunakan JSX dapat mengkompilasi ke sesuatu yang berbeda.)

Bebas kekacauan, bukan?

Perhatikan bahwa Anda masih perlu menggunakan <Fragment>sintaks jika Anda perlu memberikan keyfragmen.


Sintaks yang lebih pendek ini saat ini belum didukung di create-react-app. Refer: reactjs.org/docs/fragments.html#short-syntax
codingsplash

2
@codingsplash CRA 2.0 memilikinya sekarang.
Temui Zaveri

1
Tidak tahan dengan sepotong gula sintaksis ini, itu terlihat tidak disengaja dan menyampaikan sedikit makna yang melekat. Lebih suka<Fragment>
ESR

3
@ ESR secara pribadi saya menyukainya. Pikirkan seperti ini. Anak-anak tidak dibungkus apa pun, sama seperti tidak ada dalam <>. Tidak terlihat.
user3614030

6
  • Fitur yang ditambahkan tidak mungkin dilakukan sebelumnya dengan JSX
  • Markup JSX semantik yang lebih baik. Elemen pembungkus digunakan saat dibutuhkan bukan karena terpaksa.
  • Keseluruhan dom markup (peningkatan kinerja render dan overhead memori lebih sedikit)

Ini sesederhana ketika Anda tidak membutuhkan elemen pembungkus Anda tidak dipaksa untuk menggunakannya. Memiliki elemen yang lebih sedikit itu bagus, tetapi saya pikir manfaat terbesar adalah mampu membuat elemen dalam JSX yang sebelumnya tidak mungkin dan menambahkan makna semantik yang lebih baik untuk elemen pembungkus karena mereka opsional sekarang.

Ini tidak mungkin dilakukan sebelumnya:

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

Melirik hal-hal berikut dalam Bereaksi 15 Anda tidak dapat mengetahui apakah elemen pembungkus diperlukan atau tidak:

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

2

Sesuai reactjs.org docs kebutuhan yang paling penting dari <Fragment> </Fragment>bukan div adalah untuk menghindari semantik HTML melanggar. Ketika kita menggunakan div, bukannya <Fragment> </Fragment>kita merusak semantik HTML.

Untuk mengetahui lebih lanjut tentang html semantik. silakan klik dan ada juga kasus di mana jika Anda menggunakan div bukan Fragmen itu akan menjadi html tidak valid, misalnya lihat kode ini:

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>

Fragmen memecahkan masalah ini.


1
  1. Dengan menggunakan <React.Fragment>...</React.Fragment>, kita dapat menambahkan tag induk ke elemen JSX kami tanpa menambahkan simpul tambahan ke DOM.
  2. Anda dapat mengganti tag div tambahan dengan React.Fragment
  3. menulis React.Fragment setiap waktu terlalu lama untuk Anda. React.Fragment memiliki sintaks steno yang dapat Anda gunakan. ini<>...</>.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.