Saya memiliki objek eksternal (ke komponen) yang dapat diamati yang ingin saya dengarkan untuk perubahan. Ketika objek diperbarui itu memancarkan perubahan peristiwa, dan kemudian saya ingin rerender komponen ketika ada perubahan yang terdeteksi.
Dengan top-level React.render
hal ini dimungkinkan, tetapi di dalam komponen itu tidak berfungsi (yang masuk akal karena render
metode hanya mengembalikan objek).
Berikut contoh kode:
export default class MyComponent extends React.Component {
handleButtonClick() {
this.render();
}
render() {
return (
<div>
{Math.random()}
<button onClick={this.handleButtonClick.bind(this)}>
Click me
</button>
</div>
)
}
}
Mengklik tombol panggilan internal this.render()
, tetapi bukan itu yang sebenarnya menyebabkan rendering terjadi (Anda dapat melihat ini dalam tindakan karena teks yang dibuat oleh {Math.random()}
tidak berubah). Namun, jika saya hanya menelepon, this.setState()
bukan this.render()
, itu berfungsi dengan baik.
Jadi saya kira pertanyaan saya adalah: apakah komponen Bereaksi harus memiliki status untuk melakukan rerender? Apakah ada cara untuk memaksa komponen untuk memperbarui sesuai permintaan tanpa mengubah keadaan?
this.forceUpdate()
adalah solusi yang tepat sedangkan sisa semua jawaban dan beberapa komentar yang melawan menggunakanforceUpdate()
. Akankah itu baik-baik saja untuk mengatakan bahwa pertanyaannya belum mendapatkan solusi / jawaban yang tepat?Jawaban:
Di komponen Anda, Anda dapat menelepon
this.forceUpdate()
untuk memaksa rerender.Dokumentasi: https://facebook.github.io/react/docs/component-api.html
sumber
this.forceUpdate()
bukan solusi yang sangat baik untuk masalah penanya, itu adalah jawaban yang benar untuk pertanyaan yang diajukan dalam judul. Meskipun umumnya harus dihindari, ada situasi ketika forceUpdate adalah solusi yang baik.shouldComponentUpdate()
membuat solusi Anda sia-sia.forceUpdate
harus dihindari karena menyimpang dari pola pikir Bereaksi. Dokumen Bereaksi mengutip contoh kapanforceUpdate
dapat digunakan:Namun, saya ingin mengusulkan gagasan bahwa bahkan dengan benda bersarang yang dalam,
forceUpdate
tidak perlu. Dengan menggunakan perubahan pelacakan sumber data tidak berubah menjadi murah; perubahan akan selalu menghasilkan objek baru sehingga kita hanya perlu memeriksa apakah referensi ke objek telah berubah. Anda dapat menggunakan perpustakaan Immutable JS untuk mengimplementasikan objek data yang tidak dapat diubah ke dalam aplikasi Anda.Mengubah kunci elemen yang ingin Anda render ulang akan berfungsi. Atur prop kunci pada elemen Anda melalui keadaan dan kemudian ketika Anda ingin memperbarui setel negara untuk memiliki kunci baru.
Kemudian terjadi perubahan dan Anda mereset kunci
Saya ingin mencatat bahwa ini akan menggantikan elemen yang kuncinya berubah. Contoh di mana ini bisa berguna adalah ketika Anda memiliki bidang input file yang ingin Anda reset setelah pengunggahan gambar.
Sementara jawaban sebenarnya untuk pertanyaan OP adalah
forceUpdate()
saya menemukan solusi ini membantu dalam situasi yang berbeda. Saya juga ingin mencatat bahwa jika Anda menemukan diriforceUpdate
Anda menggunakan Anda mungkin ingin meninjau kode Anda dan melihat apakah ada cara lain untuk melakukan sesuatu.CATATAN 1-9-2019:
Di atas (mengubah kunci) sepenuhnya akan menggantikan elemen. Jika Anda menemukan diri Anda memperbarui kunci untuk membuat perubahan, Anda mungkin memiliki masalah di tempat lain dalam kode Anda. Menggunakan
Math.random()
kunci akan membuat ulang elemen dengan setiap render. Saya TIDAK akan merekomendasikan memperbarui kunci seperti ini karena bereaksi menggunakan kunci untuk menentukan cara terbaik untuk membuat ulang hal-hal.sumber
key
. Pertama, niatnya tidak jelas. Pembaca kode Anda harus bekerja keras untuk memahami mengapa Anda menggunakankey
cara ini. Kedua, ini tidak lebih murni dari padaforceUpdate
. "Murni" Bereaksi berarti bahwa presentasi visual komponen Anda 100% bergantung pada kondisinya, jadi jika Anda mengubah keadaan apa pun, pembaruan itu. Namun, jika Anda memiliki beberapa objek yang sangat bersarang (skenario yangforceUpdate
disebutkan oleh dokumen alasan untuk menggunakannya) kemudian menggunakanforceUpdate
membuatnya menjadi jelas. Ketiga,Math.random()
adalah ... acak. Secara teoritis, ini bisa menghasilkan angka acak yang sama.forceUpdate
adalah cara Bereaksi melakukan ini.Sebenarnya,
forceUpdate()
adalah satu-satunya solusi yang benar karenasetState()
mungkin tidak memicu re-render jika logika tambahan diterapkanshouldComponentUpdate()
atau ketika itu hanya kembalifalse
.mengubah paksa()
setState ()
forceUpdate()
dapat dipanggil dari dalam komponen Anda olehthis.forceUpdate()
Kait: Bagaimana saya bisa memaksa komponen untuk merender ulang dengan kait di Bereaksi?
BTW: Apakah Anda bermutasi atau properti bersarang Anda tidak menyebar?
sumber
this.state
luar konstruktor juga harus melempar kesalahan. Mungkin tidak akan melakukannya pada tahun 2016; tapi, saya cukup yakin sekarang.Saya Dihindari
forceUpdate
dengan melakukan hal berikutjadi dengan melakukan perbaikan kode seperti itu komponen Anda akan UNIK dan render secara alami
sumber
this.state.rows.map((item) => <MyComponent item={item} key={item.id} /> )
Ketika Anda ingin dua komponen Bereaksi berkomunikasi, yang tidak terikat oleh suatu hubungan (orang tua-anak), disarankan untuk menggunakan Flux atau arsitektur serupa.
Yang ingin Anda lakukan adalah mendengarkan perubahan dari toko
komponen yang dapat diamati, yang menampung model dan antarmuka, dan menyimpan data yang menyebabkan render berubah sepertistate
padaMyComponent
. Ketika toko mendorong data baru, Anda mengubah status komponen Anda, yang secara otomatis memicu render.Biasanya Anda harus menghindari penggunaan
forceUpdate()
. Dari dokumentasi:sumber
react-redux
untuk secara otomatis memetakan status store ke komponen props kapan pun diperlukan berdasarkan fungsi pemetaan yang Anda berikan.forceUpdate
gunakan kait atau HOC
Dengan menggunakan kait atau pola HOC (komponen pesanan lebih tinggi) , Anda dapat memiliki pembaruan otomatis saat toko Anda berubah. Ini adalah pendekatan yang sangat ringan tanpa kerangka kerja.
useStore Hooks cara untuk menangani pembaruan toko
withStores HOC menangani pembaruan toko
Kelas SimpleStore
Cara Penggunaan
Dalam hal kait:
Dalam kasus HOC:
PASTIKAN Untuk mengekspor toko Anda sebagai singleton untuk mendapatkan manfaat dari perubahan global seperti:
Pendekatan ini sangat sederhana dan berfungsi untuk saya. Saya juga bekerja di tim-tim besar dan menggunakan Redux dan MobX dan menemukan itu bagus juga tetapi hanya banyak boilerplate. Saya pribadi suka pendekatan saya sendiri karena saya selalu membenci banyak kode untuk sesuatu yang sederhana ketika Anda membutuhkannya.
sumber
this._data = {...this._data, ...newData}
.Jawaban lain telah mencoba menggambarkan bagaimana Anda bisa, tetapi intinya adalah bahwa Anda seharusnya tidak melakukannya . Bahkan solusi hacky untuk mengubah kunci tidak tepat sasaran. Kekuatan Bereaksi adalah melepaskan kendali mengelola secara manual ketika sesuatu harus diurai, dan sebaliknya hanya menyangkut diri Anda sendiri dengan bagaimana sesuatu harus dipetakan pada input. Kemudian sediakan aliran input.
Jika Anda perlu secara manual memaksa ulang, Anda hampir pasti tidak melakukan sesuatu dengan benar.
sumber
Anda bisa melakukannya dengan beberapa cara:
1. Gunakan
forceUpdate()
metode:Ada beberapa gangguan yang mungkin terjadi saat menggunakan
forceUpdate()
metode ini. Salah satu contoh adalah bahwa ia mengabaikanshouldComponentUpdate()
metode dan akan membuat kembali tampilan terlepas dari apakahshouldComponentUpdate()
mengembalikan false. Karena ini menggunakan forceUpdate () harus dihindari ketika memungkinkan.2. Melewati status ini ke
setState()
metodeBaris kode berikut mengatasi masalah dengan contoh sebelumnya:
Sebenarnya semua ini dilakukan adalah menimpa keadaan saat ini dengan keadaan saat ini yang memicu rendering ulang. Ini masih belum tentu cara terbaik untuk melakukan sesuatu, tetapi itu mengatasi beberapa gangguan yang mungkin Anda temui menggunakan metode forceUpdate ().
sumber
this.setState(prevState => prevState);
Ada beberapa cara untuk merender komponen Anda:
Solusi paling sederhana adalah dengan menggunakan metode forceUpdate ():
Satu lagi solusi adalah membuat kunci yang tidak digunakan di negara bagian (nonUsedKey) dan memanggil fungsi setState dengan pembaruan nonUsedKey ini:
Atau tulis ulang semua status saat ini:
Mengubah alat peraga juga menyediakan komponen rerender.
sumber
Untuk kelengkapan, Anda juga dapat mencapai ini dalam komponen fungsional:
Atau, sebagai pengait yang dapat digunakan kembali:
Lihat: https://stackoverflow.com/a/53215514/2692307
Harap dicatat bahwa menggunakan mekanisme pembaruan kekuatan masih merupakan praktik buruk karena bertentangan dengan mentalitas reaksi, sehingga harus tetap dihindari jika memungkinkan.
sumber
Kita dapat menggunakan this.forceUpdate () seperti di bawah ini.
Bagian 'Math.random' Elemen di DOM hanya akan diperbarui bahkan jika Anda menggunakan setState untuk merender ulang komponen.
Semua jawaban di sini benar melengkapi pertanyaan untuk dipahami..seperti yang kita ketahui untuk merender ulang komponen tanpa menggunakan setState ({}) adalah dengan menggunakan forceUpdate ().
Kode di atas berjalan dengan setState seperti di bawah ini.
sumber
Hanya balasan lain untuk mencadangkan jawaban yang diterima :-)
Bereaksi mencegah penggunaan
forceUpdate()
karena mereka umumnya memiliki pendekatan yang sangat "ini adalah satu-satunya cara melakukannya" menuju pemrograman fungsional. Ini bagus dalam banyak kasus, tetapi banyak pengembang Bereaksi datang dengan latar belakang OO, dan dengan pendekatan itu, sangat baik untuk mendengarkan objek yang dapat diamati.Dan jika Anda melakukannya, Anda mungkin tahu Anda HARUS membuat ulang ketika "api" yang dapat diamati, dan karena itu, Anda HARUS menggunakan
forceUpdate()
dan itu sebenarnya plus yangshouldComponentUpdate()
TIDAK terlibat di sini.Alat-alat seperti MobX, yang mengambil pendekatan OO, sebenarnya melakukan ini di bawah permukaan (sebenarnya panggilan MobX
render()
langsung)sumber
Saya telah menemukan yang terbaik untuk menghindari forceUpdate (). Salah satu cara untuk memaksa render ulang adalah dengan menambahkan dependensi render () pada variabel eksternal sementara dan mengubah nilai variabel itu saat dan ketika dibutuhkan.
Berikut contoh kode:
Sebut ini. ForceChange () saat Anda harus memaksa merender ulang.
sumber
ES6 - Saya menyertakan contoh, yang sangat membantu bagi saya:
Dalam "pernyataan singkat jika" Anda dapat melewati fungsi kosong seperti ini:
Ini tampaknya merupakan pendekatan terpendek.
sumber
forceUpdate();
Metode akan bekerja tetapi disarankan untuk digunakansetState();
sumber
Untuk mencapai apa yang Anda gambarkan, coba ini.forceUpdate ().
sumber
Cara lain adalah menelepon
setState
, DAN menjaga status:this.setState(prevState=>({...prevState}));
sumber
forceUpdate (), tetapi setiap kali saya pernah mendengar seseorang membicarakannya, sudah ditindaklanjuti dengan Anda jangan pernah menggunakan ini.
sumber
Anda dapat menggunakan forceUpdate () untuk memeriksa detail lebih lanjut ( forceUpdate () ).
sumber