React 16 içindeki Fragmanlar neden konteyner div 'den daha iyi?


165

React 16.2'de geliştirilmiş destek Fragmentseklendi. Daha fazla bilgiyi React'in blog yayınında bulabilirsiniz.

Hepimiz aşağıdaki kodu biliyoruz:

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

Evet, bir konteyner divine ihtiyacımız var, ama bu büyük bir anlaşma değil.

React 16.2'de, çevreleyen konteyner div'ini önlemek için bunu yapabiliriz:

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

Her iki durumda da, iç elemanları çevreleyen bir kap elemanına ihtiyacımız var.

Sorum şu: Neden Fragmenttercih ediliyor? Performansa yardımcı olur mu? Öyleyse neden? Biraz içgörü isterdim.


2
Bir ebeveyn için ilk seviye çocuklar oluştururken flexbox stil için gerçekten yararlı buluyorum
willwoo

32
Sorun, divher zaman bir sarmalayıcı öğesi istememenizdir. Sarma öğelerinin bir anlamı vardır ve genellikle bu anlamın kaldırılması için ek stillere ihtiyacınız vardır. <Fragment>sadece işlenmemiş sözdizimsel şekerdir. Sarıcı oluşturmanın çok zor olduğu durumlar vardır, örneğin SVG'de <div>kullanılamayan ve <group>her zaman istediğiniz şey değildir.
Sulthan

Yanıtlar:


305
  1. Biraz daha hızlı ve daha az bellek kullanımı var (ekstra bir DOM düğümü oluşturmaya gerek yok). Bunun sadece çok büyük ve / veya derin ağaçlarda gerçek bir yararı vardır, ancak uygulama performansı genellikle bin kesimle ölümden muzdariptir. Bu daha az kesilmiş.
  2. Flexbox ve CSS Grid gibi bazı CSS mekanizmalarının özel bir ebeveyn-çocuk ilişkisi divvardır ve ortada s eklemek, mantıksal bileşenleri ayıklarken istenen düzeni korumayı zorlaştırır.
  3. DOM müfettişi daha az karmaşıktır. :-)

Bu React sayısında diğer bazı kullanım durumlarının açıklamalarını bulabilirsiniz: Birden çok bileşenin render'dan döndürülmesine izin vermek için parça API'sı ekleyin


24
4. Tanım listeleri yazmak <dt><dd>çok daha kolay. Eşleştirilmiş öğeleri döndürmek daha önce garipti Fragments.
Sonson123

Parçalar tepkisel olarak çalışıyor mu? Denedim import Fragment from 'react'. Ama RN'de tanımsız.
binchik

3
Çünkü number 2, tablolar aslında bizim için en büyük sorun olmuştur. Bazı garip React kodu için yapılmış table>tr>td(muhtemelen theadve benzer) gerekli yapısı .
Matsemann

2
@binchik denedi import {Fragment} from 'react'mi? adlandırılmış bir dışa aktarma.
Soska

1
3 numara en önemlisidir!
Zach Smith

28

Yukarıdaki tüm cevaplara ek olarak bir avantaj daha var: kod okunabilirliği , Fragmentbileşen sözdizimsel bir şeker formunu destekler <>,. Böylece sorunuzdaki kod daha kolay yazılabilir:

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

Dokümanlara göre ,

React'te bu <React.Fragment/>, önceki bölümdeki örnekte olduğu gibi bir öğeye açılır . (JSX kullanan Tepki Dışı çerçeveler farklı bir şeye derlenebilir.)

Dağınıklık yok, değil mi?

Parçayı <Fragment>sağlamanız gerekiyorsa yine de sözdizimi kullanmanız gerektiğini unutmayın key.


Bu daha kısa sözdizimi henüz create-tepki uygulaması için henüz desteklenmemektedir. Bakınız: reaktjs.org/docs/fragments.html#short-syntax
codingsplash

2
@codingsplash CRA 2.0 şimdi sahip.
Zaveri ile tanışın

1
Bu sözdizimsel şekere dayanamıyorum, kasıtsız görünüyor ve çok az doğal anlam taşıyor. Çok tercih<Fragment>
ESR

3
@ESR şahsen beğendim. Bu şekilde düşün. Çocuklar hiçbir şeye sarılmamış, tıpkı <> da hiçbir şey yokmuş gibi. Görünmez.
user3614030

6
  • Daha önce JSX ile mümkün olmayan özellikler eklendi
  • Daha iyi anlamsal jsx işaretlemesi. Sarma elemanları, gerektiğinde zorlandıkları için kullanılmazlar.
  • Daha az genel dom işaretlemesi (artırılmış oluşturma performansı ve daha az bellek ek yükü)

Bir sarmalayıcı elemanına ihtiyacınız olmadığında olduğu kadar basit bir tane kullanmak zorunda kalmazsınız. Daha az öğeye sahip olmak harika ama bence en büyük fayda, daha önce mümkün olmayan öğeleri jsx oluşturabilme ve şimdi isteğe bağlı oldukları için sarıcı öğelere daha iyi anlamsal anlam ekleyebilme.

Bu daha önce mümkün değildi:

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

React 15'te aşağıdakilere bakarak, sarıcı elemanın gerekli olup olmadığını söyleyemezsiniz:

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

2

Reaktjs.org belgelerine göre<Fragment> </Fragment> , div yerine bunun yerine en önemli ihtiyaç HTML anlambilimini bozmaktan kaçınmaktır. Bunun yerine <Fragment> </Fragment>div'leri kullandığımızda HTML anlambilimini bozuyoruz.

HTML semantiği hakkında daha fazla bilgi. lütfen tıklayın ve ayrıca Fragments yerine div's kullanıyorsanız geçersiz html olacağı durumlar vardır, örneğin şu koda bakın:

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>

Parçalar bu sorunu çözer.


1
  1. Kullanılması <React.Fragment>...</React.Fragment>, biz DOM fazladan düğümü eklemeden bizim JSX elemanlarına bir üst etiketi ekleyebilirsiniz.
  2. ekstra div etiketlerini React.Fragment ile değiştirebilirsiniz.
  3. React.Fragment her zaman sizin için çok uzun. React.Fragment, kullanabileceğiniz bir steno sözdizimine sahiptir. Bu<>...</>.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.