React: Peringatan tak terduga saat menghidrasi dengan portal dan SSR

Dibuat pada 15 Apr 2018  ·  24Komentar  ·  Sumber: facebook/react

Apakah Anda ingin meminta fitur atau melaporkan bug ?

bug

Bagaimana perilaku saat ini?

Diberikan cuplikan berikut (disederhanakan):

class HoverMenu extends React.Component {
  render() {
    if (typeof document === 'undefined') return null
    const root = document.getElementById('root')
    return ReactDOM.createPortal(<div>Hello World</div>, root)
  }
}

class Para extends React.Component {
  render() {
    return (
      <span>
        Some Text
        <HoverMenu />
      </span>
    )
  }
} 

di mana div#root adalah div yang valid yang ada, kesalahan berikut ini ditampilkan saat menghidrasi setelah SSR:

Warning: Expected server HTML to contain a matching <div> in <span>

Peringatan itu hilang jika saya memperbarui definisi HoverMenu menjadi:

class HoverMenu extends React.Component {
  componentDidMount() {
    this.setState({ isActive: true })
  }
  render() {
    const { isActive} = this.state
    if (!isActive) return null
    const root = document.getElementById('root')
    return ReactDOM.createPortal(<div>Hello World</div>, root)
  }
}

Saya memilih untuk tidak melakukannya karena rendering ganda yang disebabkan oleh setState dalam componentDidMount .

Saya tidak begitu mengerti apa yang dikatakan kesalahan itu kepada saya. Tidak ada <div /> yang diberikan sisi server dalam kedua kasus. Kesalahan ini sangat membingungkan, karena HoverMenu DOM div bahkan tidak ditampilkan di dalam DOM span . (Saya ingin tahu apakah ini terjadi karena HoverMenu berada di dalam React span .)

Apa perilaku yang diharapkan?

Tidak ada kesalahan yang terjadi. Atau, setidaknya pesan kesalahannya lebih jelas.

Versi React mana, dan browser / OS mana yang terpengaruh oleh masalah ini?

Chrome 65
Bereaksi 16.2
(SSR sampai Next 5.1)

medium Bug good first issue

Komentar yang paling membantu

Meskipun portal hidrasi tidak didukung (https://github.com/facebook/react/issues/13097), pesan itu sendiri tidak masuk akal. Kami harus menyelidiki dan memperbaikinya.

Semua 24 komentar

Saya memiliki masalah serupa, yang juga dapat diselesaikan dengan rendering ulang pada klien melalui setState.
Dalam kasus saya, saya mencoba membuat modal di dalam portal. Komponen Modal mengembalikan null saat dirender di server dan membuat portal di klien. Namun, DOM menjadi kacau setelah hidrasi.

Misalnya jika saya menggunakannya seperti ini di dalam komponen utama saya:

<Modal>
This is a test
</Modal>

<div className="some-div-after-the-modal">
</div>

Alih-alih mendapatkan ini setelah hidrasi:

<!-- Inside the portal container -->
<div class="modal-wrapper">
    <div class="modal-content">This is a test</div>
</div>

<!-- In the main component -->
<div class="some-div-after-the-modal">
</div>

Saya mengerti ini:

<!-- Inside the portal container -->
<div class="some-div-after-the-modal">
    <div class="modal-content">This is a test</div>
</div>

<!-- In the main component -->
<div class="some-div-after-the-modal">
</div>

Dan peringatannya sama ( Expected server HTML to contain a matching <div> in <div> ). Saya menggunakan React 16.3 dengan metode SSR khusus.

Saya tidak yakin apakah ini perilaku yang dimaksudkan.

Meskipun portal hidrasi tidak didukung (https://github.com/facebook/react/issues/13097), pesan itu sendiri tidak masuk akal. Kami harus menyelidiki dan memperbaikinya.

@gaearon Tujuan perbaikan adalah

  • [] Mendeteksi Portal sedang digunakan dalam hydrate () dan kemudian membuang pesan kesalahan dengan lebih tepat oleh invariant.
    misal invariant violation: Portal is not support on SSR. For more detail, please refer https://github.com/facebook/react/issues/13097
  • [] Tambahkan Tes

    • [] Jika Portal digunakan dengan hydrate (), harus membuang pesan kesalahan di atas

Baik?
Saya bersedia jika tidak mendesak.

Saya sedang merencanakan draf dokumen SSR ke repo website, jadi saya harus paham mekanisme hidratnya.
Saya pikir penyelidikan ini akan membantu rencana saya.
https://github.com/facebook/react/pull/13379

Mengapa Portal tidak didukung di SSR, bahkan untuk merender "tidak ada"?

Sepertinya rendering tidak ada yang terbaik - Saya tidak melihat apa yang membuat konten portal berbeda sehingga kami tidak menganggapnya pantas untuk rendering server.

Kami kemungkinan akan kembali ke ini bersama dengan perombakan perender server untuk ketegangan.

Portal secara konseptual adalah komponen khusus klien; digunakan untuk hal-hal seperti modal yang biasanya tidak ingin dirender di server - mereka juga mengambil elemen dom, yang tidak direnderToString karena tidak ada dom. Saya tidak melihat bagaimana ada sesuatu yang berarti untuk dilakukan dengan mereka di server - saya juga tidak melihat sesuatu yang berharga dari melempar.

digunakan untuk hal-hal seperti modal

Itu salah satu kasus penggunaan tetapi ada juga yang lain seperti sidebar dan sejenisnya yang belum tentu hanya untuk klien.

mereka juga mengambil elemen dom

Benar - dalam desain saat ini. Itu bisa berubah. https://github.com/facebook/react/pull/8386#issuecomment -262375265

Saya juga tidak melihat sesuatu yang berharga dari melempar.

Nilai melempar adalah secara eksplisit mengakui bahwa portal tidak akan berfungsi. Anda dapat dengan mudah mengatasinya dengan {domNode && ReactDOM.createPortal(stuff, domNode)} atau yang serupa. Karena Anda sudah harus melakukan beberapa jenis pemeriksaan untuk menentukan apakah Anda bisa mendapatkan simpul DOM - jadi pada tahap ini Anda harus memiliki cukup data untuk memilih untuk tidak memancarkan portal.

Saya ingin memperbaikinya sebagai "masalah pertama yang baik"

+1

Bisakah saya mengatasi masalah ini?

Tentu. Saya rasa Anda bisa. Jadi seberapa jauh Anda telah pergi? Saya sebenarnya berpikir untuk mengambilnya juga.

  • 2

Hai teman-teman, tahu bagaimana saya dapat menemukan file di mana masalahnya, saya bisa mendapatkannya tolong bantu.

Hai, ini permintaan penarikan sebagian untuk masalah ini
https://github.com/facebook/react/pull/15473

Adakah yang masih melakukan ini? Saya ingin menerimanya.

Apa statusnya ini? Bagaimana saya bisa mereproduksinya?

Apakah ini masih menjadi masalah?

Saya juga belum mendapat tanggapan tentang masalah ini.

Saya yakin status masalah ini masih terbuka.

Bisakah saya mengatasi masalah ini?

Halo, apakah ada yang menangani masalah ini? Jika tidak, saya ingin menerimanya.

jika tidak ada yang mengerjakannya, saya bisa

Apakah ini masih menjadi masalah? Sepertinya ada upaya untuk memperbaikinya, tetapi masalah yang mendasarinya adalah bahwa beberapa orang sebenarnya ingin portal bekerja pada rendering sisi server? Jika demikian, bisakah masalah ini ditutup?

Menambahkan elemen div seharusnya berfungsi dengan baik

`class Para extends React.Component {
render () {
kembali (

Beberapa Teks
)

}
} `

Apakah halaman ini membantu?
0 / 5 - 0 peringkat