React: Memanipulasi DOM di componentDidUpdate

Dibuat pada 23 Sep 2016  ·  3Komentar  ·  Sumber: facebook/react

Hai, ini lebih seperti pertanyaan, saya ingin membuka diskusi tentang manipulasi DOM di componentDidUpdate .

Saya sedang membuat plugin Bereaksi. Itu harus melakukan beberapa perhitungan DOM, karena CSS tidak cukup kuat untuk mencakup semua yang perlu dilakukan plugin ini. Masalahnya adalah saya perlu menyesuaikan beberapa properti CSS tergantung pada nilai pengembalian getBoundingClientRect() dari beberapa elemen DOM lain yang dirender oleh component yang sama .

Jadi secara teknis kami memiliki 3 opsi:

1) Hitung getBoundingClientRect di componentDidUpdate dan panggil setState dengan nilai yang dihitung. Saya takut loop tak terbatas yang bisa terjadi dalam kasus-kasus tertentu, jadi saya tidak akan memilih yang ini.

2) Lakukan seperti di 1) dan mainkan sedikit dengan shouldComponentUpdate , tetapi ini tampaknya sangat rumit dan tidak dapat dibaca. Banyak pertanyaan muncul yang bergantung pada kasus penggunaan tertentu.

3) Perbarui DOM dari componentDidUpdate. Ini adalah solusi yang saya putuskan untuk digunakan, ini berfungsi, sederhana, stabil, dan berfungsi sebagaimana dimaksud. Namun saya merasa saya berada di tepi, jadi saya ingin memeriksa ulang bahwa ini adalah cara yang OK untuk melakukan sesuatu. Apakah boleh memanipulasi DOM di componentDidUpdate ? Itu dipanggil setiap kali render selesai, dan saya setuju untuk membuang perubahan saya, karena untuk render saya akan memodifikasi DOM lagi.

Berikut adalah bagian dari kode

componentDidMount() {
  this.recalculateIndent();
}

componentDidUpdate() {
  this.recalculateIndent();
}

recalculateIndent() {
  // calculate indent based on getBoundingClientRect of some DOM reference
  this.textareaRef.style.textIndent = `${indent}px`;
}

render() {
   return (
   ...
   <textarea ref={ref => this.textareaRef = ref}/>
   ...
   );
}

Komentar yang paling membantu

@jvorcak menggunakan componentDidUpdate adalah tempat yang tepat untuk memanipulasi DOM secara manual setelah render. Per dokumen:

Gunakan ini sebagai kesempatan untuk mengoperasikan DOM ketika komponen telah diperbarui.

Selain itu, kami mencoba menggunakan pelacak masalah hanya untuk permintaan fitur dan laporan bug. Pertanyaan penggunaan harus diarahkan ke tempat lain, seperti diskusi.reactjs.org atau StackOverflow. Terima kasih!

Semua 3 komentar

Setiap solusi (metode siklus hidup komponen) sesuai untuk situasi konkret, tetapi manipulasi DOM salah. Gunakan komponen status dan render ulang. Contoh untuk kasus penggunaan terakhir saya "tajuk tetap untuk tabel + pengguliran virtual untuk badan tabel", saya harap ini akan membantu Anda memahami aliran yang benar.

  1. Konstruktor komponen: nilai status awal: bodyHeight = 0 (atau null, sesuka Anda).
  2. Render pertama, merender header tabel tetapi badan tabel kosong (0 baris).
  3. componentDidMount - baca tinggi header dan container DOM (+ beberapa perhitungan...) dan setState untuk bodyHeight (re-render).
  4. Render kedua, bodyHeight !== 0, badan tabel akan dirender. Sekarang, parameter ketinggian diketahui ( saya dapat mengaturnya menggunakan prop komponen "gaya", daripada manipulasi DOM ), saya dapat menambahkan komponen untuk baris.
  5. Pendengar acara tambahan untuk "mengubah ukuran" (mengubah ukuran dokumen/browser), tambahkan componentDidMount, hapus di componentWillUnmount. Di event handler saya melakukan hal yang sama seperti di componentDidMount - baca nilai tinggi DOM baru dan setState.
  6. Tidak ada manipulasi DOM dengan tangan, reaksi berhasil.

@jvorcak menggunakan componentDidUpdate adalah tempat yang tepat untuk memanipulasi DOM secara manual setelah render. Per dokumen:

Gunakan ini sebagai kesempatan untuk mengoperasikan DOM ketika komponen telah diperbarui.

Selain itu, kami mencoba menggunakan pelacak masalah hanya untuk permintaan fitur dan laporan bug. Pertanyaan penggunaan harus diarahkan ke tempat lain, seperti diskusi.reactjs.org atau StackOverflow. Terima kasih!

Bagaimana jika Anda ingin memperbarui satu Komponen setelah mengubah sesuatu di komponen lain?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat