Bir React Fragment, bir bileşenin birkaç öğeyi fazladan bir <div> ile sarmadan döndürmesini sağlar. İlk öğeden önce <>, sonuncudan sonra </> yaz; React öğeleri sayfada kendine ait bir düğüm olmadan doğrudan ebeveynin içine koyar.
Her Greeting yan yana bir başlık ve bir paragraf döndürür. <> ve </> satırlarını sil; önizleme bunun yerine bir derleme hatası gösterir, çünkü fonksiyon artık iki değer döndürmeye çalışıyor.
Bir bileşenin neden tek bir köke ihtiyacı var
JSX, fonksiyon çağrıları yazmanın daha hoş bir yoludur. <h2>Hi</h2> kabaca jsx('h2', { children: 'Hi' }) olarak derlenir; tek bir ifade. Bir return deyimi tek bir değer döndürebilir, bu yüzden etrafında hiçbir şey olmayan iki kardeş etiket return a b yazmak gibidir: derleyici "Adjacent JSX elements must be wrapped in an enclosing tag" hatasıyla durur.
Fragment'lar var olmadan önce çözüm bir sarmalayıcı <div> idi. Bu işe yarar, ama div gerçek bir öğedir. DOM'da görünür, CSS yerleşimine katılır ve bazı ebeveynler onu çocuk olarak hiç kabul etmez. Bir fragment tek kök kuralını karşılar ve sonra ortadan kaybolur.
Hiçbir şey eklemediğini görebilirsin. Aşağıdaki örnek aynı iki öğeyi bir fragment ve bir div aracılığıyla render eder, sonra her kapsayıcının doğrudan çocuklarını sayar.
Konsol fragment için 2 (iki span), onları saran div için de 1 yazdırır. Bir flex ya da grid kapsayıcısında bu fark, span'lerin ayrı öğeler olarak mı yerleştirileceğine yoksa tek bir öğede mi toplanacağına karar verir.
Kısa sözdizimi ve Fragment bileşeni
Bir fragment yazmanın iki yolu vardır ve ikisi aynı şeye derlenir:
import { Fragment } from 'react';
// Short syntax, no import needed
<>
<dt>React</dt>
<dd>A library for building user interfaces</dd>
</>
// Long form
<Fragment>
<dt>React</dt>
<dd>A library for building user interfaces</dd>
</Fragment>
Neredeyse her yerde <>...</> kullan. <Fragment>'a tek bir durumda başvur: fragment'ın bir key'e ihtiyacı olduğunda. Kısa sözdizimi özellik alamaz, bu yüzden <key={id}> geçerli bir JSX değildir. Eski kodda <React.Fragment> da görebilirsin; bu, varsayılan React import'u üzerinden erişilen aynı bileşendir.
Listelerde key'li fragment'lar
map ile bir liste render ettiğinde, React'in render'lar arasında takip edebilmesi için her öğenin bir key'e ihtiyacı vardır (nedenini listeler ve key'ler sayfası anlatıyor). Her öğe tek bir öğe yerine bir grup öğeyse key fragment'a gider, bu yüzden uzun biçime ihtiyacın olur.
Klasik durum bir tanım listesidir: her giriş bir <dt> ve bir <dd>'dir ve bir <dl> bunları doğrudan içermelidir.
Reverse'e tıkla; çiftler bütün birimler olarak yer değiştirir, çünkü her çiftin kendi key'i vardır. Her çiftin etrafındaki bir sarmalayıcı <div> da key alabilirdi ve bir dl içinde geçerli HTML'dir, ama işaretlemeye bir fragment'ın dışarıda tuttuğu üçüncü bir seviye ekler.
Tablolar içinde fragment'lar
Başıboş bir sarmalayıcının en çok zarar verdiği yer tablolardır. Bir <tr>, doğrudan çocukları olarak <td> ve <th> hücreleri bekler. Birkaç hücre döndüren bir bileşen onları bir <div> ile sararsa tarayıcı div'i tek bir garip hücre olarak ele alır ve içindeki hücreler başlıkla hizalanmayı bırakır.
Fragment satırında fiyat Price altında, stok da Stock altında durur. Div satırında iki hücre de Price sütununa sıkışır ve Stock sütunu boş kalır. Geliştirmede React ayrıca bir <div>'in bir <tr>'nin çocuğu olamayacağına dair bir uyarı kaydeder; önizleme bir production derlemesi gibi çalışır, bu yüzden bu kontrolü atlar ve burada gördüğün bozuk yerleşimdir. Sunucu tarafı render ile aynı hata hydration hatalarına da yol açabilir, çünkü tarayıcının HTML ayrıştırıcısı yanlış yerdeki div'i taşır.
Aynı kural <li> öğeleri içermesi gereken <ul> ve <ol> için ve <option> öğeleri içermesi gereken <select> için de geçerlidir. Bir bileşen böyle bir ebeveynin doğrudan içine ait parçalar döndürdüğünde bir fragment döndür.
Fragment'lar ya da diziler
Bir bileşen bir öğe dizisi de döndürebilir ve React bunları bir fragment gibi sırayla render eder. Döndürülen bir dizideki her öğenin, tıpkı map çıktısı gibi, kendi key'ine ihtiyacı vardır, çünkü React diziyi bir liste olarak ele alır:
function Cells() {
return [<td key="price">$4</td>, <td key="stock">In stock</td>];
}
Bu çalışır, ama daha gürültülüdür: öğeler arasında virgüller, her birinde bir key ve işaretleme büyüdükçe gözden kaçması kolay bir köşeli parantez. Sabit bir öğe grubu için bir fragment kullan, dizileri de doğal oldukları şey için, yani veri üzerinde map'lemenin sonucu için sakla.
Bir fragment'ın yapamadıkları
Bir fragment hiçbir öğe render etmediği için bir sınıf, bir stil, bir olay işleyicisi ya da bir ref koyacak yeri yoktur. <Fragment className="row"> işe yarar bir şey yapmaz ve React'in bir fragment'tan okuduğu tek prop key'dir. Grubu stillendirmen ya da üzerindeki tıklamaları dinlemen gerektiğinde gerçekten gerçek bir öğeye ihtiyacın vardır ve bu sorun değil: durduğu yerde geçerli olan birini seç, örneğin satırları gruplamak için bir <tbody> ya da bir liste öğesini tutmak için bir <li>.
Bir fragment, bir öğenin çalıştığı her yerde çalışır, koşullu render dahil: {show && <>...</>} tüm grubu tek seferde gösterir ya da gizler.
Sıkça Sorulan Sorular
React'te Fragment nedir?
Fragment, bir bileşenin bir DOM düğümü eklemeden birkaç öğeyi tek bir değer olarak döndürmesini sağlayan bir sarmalayıcıdır. <><h1 /><p /></>, h1 ve p'yi doğrudan ebeveynin içine koyar.
<> ile <Fragment> arasındaki fark nedir?
Aynı şeyi üretirler. <>...</> kısa sözdizimidir. <Fragment> ise react'ten import ettiğin uzun biçimdir ve bir key alabilen tek biçimdir; fragment'ları bir listede render ettiğinde buna ihtiyacın olur.
Neden div yerine Fragment kullanılır?
Div gerçek bir öğedir. Doğrudan çocuk bekleyen yerleşimleri (flex ve grid kapsayıcıları, ul, table, tr) bozabilir ve DOM'a gürültü ekler. Fragment hiçbir şey eklemez.
Bir Fragment'ın className ya da onClick'i olabilir mi?
Hayır. Fragment hiçbir öğe render etmez, yani bir sınıf, stil ya da olay işleyicisi koyacak bir şey yoktur. Kabul ettiği tek prop key'dir. Bunlardan birine ihtiyacın varsa gerçek bir öğe kullan.
Neden "Adjacent JSX elements must be wrapped in an enclosing tag" hatası alıyorum?
Bir bileşen etrafında hiçbir şey olmayan iki kardeş öğe döndürdü. JSX tek bir ifadeye derlenir, bu yüzden kardeşleri <>...</> ile sar.