Bagaimana cara menghindari pembungkus ekstra <div> di React?

114

Hari ini saya sudah mulai belajar ReactJS dan setelah satu jam dihadapkan pada masalah .. Saya ingin memasukkan sebuah komponen yang memiliki dua baris di dalam div pada halaman. Contoh sederhana dari apa yang saya lakukan di bawah ini.

Saya memiliki html:

<html>
..
  <div id="component-placeholder"></div>
..
</html>

Render fungsi seperti ini:

...
render: function() {

    return(
        <div className="DeadSimpleComponent">
            <div className="DeadSimpleComponent__time">10:23:12</div >
            <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
        </div>
    )
}
....

Dan di bawah ini saya memanggil render:

ReactDOM.render(<DeadSimpleComponent/>, document.getElementById('component-placeholder'));

HTML yang dihasilkan terlihat seperti ini:

<html>
..
  <div id="component-placeholder">
    <div class="DeadSimpleComponent">
            <div class="DeadSimpleComponent__time">10:23:12</div>
            <div class="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
    </div>
</div>
..
</html>

Masalah yang saya tidak terlalu senang yaitu React memaksa saya untuk membungkus semua dalam div "DeadSimpleComponent". Apa solusi terbaik dan sederhana untuk itu, tanpa manipulasi DOM eksplisit?

UPDATE 28/7/2017: Maintainers of React menambahkan kemungkinan itu di React 16 Beta 1

Sejak React 16.2 , Anda dapat melakukan ini:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}
Kirill Reznikov
sumber
4
praktik penamaan yang sempurna ;-)
Kirill Reznikov
Bisakah saya melihat file HTML Anda? Saya salah membaca pertanyaan Anda. Saya mungkin punya solusi.
Louis93
Smth seperti ini: jsfiddle.net/qawumm3v
Kirill Reznikov
Anda memiliki masalah dengan komponen yang memiliki satu elemen? Betulkah?
Dominic
Maksud kamu apa? Saya hanya mencoba React, seharusnya tidak terlalu rumit .. Tapi batasan terlihat mengganggu.
Kirill Reznikov

Jawaban:

142

Persyaratan ini telah dihapus pada versi React (16.0)] 1 , jadi sekarang Anda dapat menghindari pembungkus itu.

Anda dapat menggunakan React.Fragment untuk membuat daftar elemen tanpa membuat node induk, contoh resmi:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

Selengkapnya di sini: Fragmen

Luger
sumber
1
Berita bagus DmitryUlyanets. Apakah ada tanggal rilis yang direncanakan?
Jonas Carlbaum
Ini dirilis sejak 26 September 2017, lihat reactjs.org/blog/2017/09/26/react-v16.0.html
Tom
56

Perbarui 2017-12-05: React v16.2.0 sekarang sepenuhnya mendukung rendering fragmen dengan dukungan yang ditingkatkan untuk mengembalikan banyak turunan dari metode render komponen tanpa menentukan kunci pada turunan :

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

Jika Anda menggunakan versi React sebelum v16.2.0, Anda juga bisa menggunakan <React.Fragment>...</React.Fragment>:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

Asli:

React v16.0 memperkenalkan pengembalian array elemen dalam metode render tanpa membungkusnya dalam div: https://reactjs.org/blog/2017/09/26/react-v16.0.html

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

Saat ini, kunci diperlukan untuk setiap elemen untuk menghindari peringatan kunci tetapi ini dapat diubah di rilis mendatang:

Di masa mendatang, kami mungkin akan menambahkan sintaks fragmen khusus ke JSX yang tidak memerlukan kunci.

Tom
sumber
Sintaks singkat baru <> </> sangat bagus. Namun, saya masih memiliki banyak perasaan campur aduk tentang itu.
Thulani Chivandikwa
@ThulaniChivandikwa Apakah Anda keberatan untuk menyuarakan keraguan Anda tentang sintaks singkat?
Tom
1
Saya pikir ini lebih tentang konsep tag kosong menjadi aneh di BEJ dan tidak terlalu intuitif kecuali Anda tahu persis apa fungsinya.
Thulani Chivandikwa
7

Kamu bisa memakai:

render(){
    return (
        <React.Fragment>
           <div>Some data</div>
           <div>Som other data</div>
        </React.Fragment>
    )
}

Untuk detail lebih lanjut, lihat dokumentasi ini .

Rolando Cintron
sumber
3

Gunakan [], bukan () untuk membungkus keseluruhan pengembalian.

render: function() {
  return[
    <div className="DeadSimpleComponent__time">10:23:12</div >
    <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
  ]
}
Michael Cuneo
sumber
1

Ini masih diperlukan , TAPI React sekarang pastikan untuk membuat elemen tanpa membuat elemen DOM tambahan.

Pembungkusan ekstra diperlukan (biasanya dengan induk div) karena createElementmetode Reacts memerlukan typeparameter yaitu either a tag name string (such as 'div' or 'span'), a React component type (a class or a function). Tapi ini sebelum mereka memperkenalkan React Fragment.

Lihat dokumen api BARU ini untuk createElement

React.createElement : Membuat dan mengembalikan elemen React baru dari tipe yang diberikan. Argumen type dapat berupa string nama tag (seperti 'div' atau 'span'), jenis komponen React (kelas atau fungsi), atau jenis fragmen React .

berikut adalah contoh resminya, Refer React.Fragment .

render() {
  return (
    <React.Fragment>
      Some text.
      <h2>A heading</h2>
    </React.Fragment>
  );
}
utama
sumber
0

Anda tidak akan bisa menyingkirkan divelemen itu. React.render () perlu mengembalikan satu simpul DOM yang valid.

Henrik Andersson
sumber
div diabaikan, Knockout.JS melakukan hal yang sama. memiliki div tanpa gaya di bagian luar komponen Anda tidak menimbulkan efek apa pun.
Chris Hawkes
16
@ChrisHkes, tidak setuju. satu div pembungkus mempengaruhi pemilih css.
Downhillski
Saat bekerja dengan elemen semantik, yang Anda tidak ingin menjadi komponen React seluruhnya, ini menjadi masalah. Katakanlah ada tag bagian dengan elemen header dan footer, dan di antara mereka ada penampung peta google, yang tidak ingin kita gunakan dalam React. Maka akan lebih baik jika memiliki header sebagai komponen React dan Footer sebagai komponen React, tanpa harus menyertakan div: s tambahan di luar di dalam komponen React ... Itu adalah desain yang bodoh, jika Anda benar-benar peduli dengan html Anda mengeluarkan ...
Jonas Carlbaum
0

Berikut salah satu cara untuk merender komponen "transculent":

import React from 'react'

const Show = (props) => {
  if (props.if || false) {
    return (<React.Fragment>{props.children}</React.Fragment>)
  }
  return '';
};

----


<Show if={yomama.so.biq}>
    <img src="https://yomama.so.biq">
    <h3>Yoamama</h3>
<Show>

masukkan deskripsi gambar di sini

Ярослав Рахматуллин
sumber
0

Ada solusi juga. Kode blok di bawah ini menghasilkan fragmen tanpa memerlukan React.Fragment.

return [1,2,3].map(i=>{
if(i===1) return <div key={i}>First item</div>
if(i===2) return <div key={i}>Second item</div>
return <div key={i}>Third item</div>
})
erfan seidipoor
sumber
0

Saya tahu pertanyaan ini telah terjawab, Anda tentu saja dapat menggunakan React.Fragment yang tidak membuat node tetapi memungkinkan Anda mengelompokkan hal-hal seperti div.

Selain itu, jika Anda ingin bersenang-senang, Anda dapat menerapkan (dan mempelajari banyak hal) mode React yang menghapus div ekstra dan untuk ini saya benar-benar ingin membagikan video yang bagus tentang bagaimana Anda dapat melakukannya di basis kode react itu sendiri.

https://www.youtube.com/watch?v=aS41Y_eyNrU

Ini tentu saja bukan sesuatu yang akan Anda lakukan dalam praktik tetapi ini adalah kesempatan belajar yang baik.

Gabriel P.
sumber