Saya memiliki aplikasi tempat saya perlu mengatur ketinggian elemen (katakanlah "konten-aplikasi") secara dinamis. Dibutuhkan ketinggian "chrome" dari aplikasi dan kurangi itu dan kemudian atur ketinggian "app-content" agar sesuai dengan 100% dalam batasan itu. Ini super sederhana dengan tampilan vanilla JS, jQuery, atau Backbone, tapi saya berjuang untuk mencari tahu proses apa yang tepat untuk melakukan ini di React?
Di bawah ini adalah contoh komponen. Saya ingin dapat mengatur app-content
tinggi menjadi 100% dari jendela dikurangi ukuran ActionBar
dan BalanceBar
, tetapi bagaimana saya tahu kapan semuanya dirender dan di mana saya akan meletakkan barang perhitungan di Kelas Bereaksi ini?
/** @jsx React.DOM */
var List = require('../list');
var ActionBar = require('../action-bar');
var BalanceBar = require('../balance-bar');
var Sidebar = require('../sidebar');
var AppBase = React.createClass({
render: function () {
return (
<div className="wrapper">
<Sidebar />
<div className="inner-wrapper">
<ActionBar title="Title Here" />
<BalanceBar balance={balance} />
<div className="app-content">
<List items={items} />
</div>
</div>
</div>
);
}
});
module.exports = AppBase;
javascript
reactjs
Oscar Godson
sumber
sumber
Jawaban:
componentDidMount ()
Metode ini dipanggil sekali setelah komponen Anda dirender. Jadi kode Anda akan terlihat seperti itu.
sumber
componentDidUpdate
jika nilai dapat berubah setelah render pertama.componentDidMount()
tidak menyebabkan transisi.componentDidMount: () => { setTimeout(addClassFunction())}
, atau menggunakan rAF, jawaban di bawah ini memberikan jawaban ini.Salah satu kelemahan menggunakan
componentDidUpdate
, ataucomponentDidMount
mereka benar-benar dieksekusi sebelum elemen dom selesai dibuat, tetapi setelah mereka telah diteruskan dari Bereaksi ke DOM browser.Katakan misalnya jika Anda perlu mengatur node.scrollHeight ke node.scrollTop yang diberikan, maka elemen DOM Bereaksi mungkin tidak cukup. Anda harus menunggu sampai elemen selesai dicat untuk mendapatkan ketinggiannya.
Larutan:
Gunakan
requestAnimationFrame
untuk memastikan bahwa kode Anda dijalankan setelah lukisan objek yang baru Anda rendersumber
_this.getDOMNode is not a function
apa kode ini?Dalam pengalaman saya
window.requestAnimationFrame
tidak cukup untuk memastikan bahwa DOM telah sepenuhnya diberikan / reflow-complete fromcomponentDidMount
. Saya memiliki kode yang menjalankan yang mengakses DOM segera setelahcomponentDidMount
panggilan dan menggunakan hanyawindow.requestAnimationFrame
akan menghasilkan elemen yang ada di DOM; namun, pembaruan dimensi elemen belum tercermin karena belum ada reflow.Satu-satunya cara yang benar-benar dapat diandalkan untuk bekerja adalah membungkus metode saya dalam
setTimeout
danwindow.requestAnimationFrame
untuk memastikan tumpukan panggilan React saat ini akan dihapus sebelum mendaftar untuk render frame berikutnya.Jika saya harus berspekulasi tentang mengapa ini terjadi / perlu saya bisa melihat Bereaksi DOM pembaruan batching dan tidak benar-benar menerapkan perubahan ke DOM sampai setelah tumpukan saat ini selesai.
Pada akhirnya, jika Anda menggunakan pengukuran DOM dalam kode yang Anda jalankan setelah panggilan balik Bereaksi Anda mungkin ingin menggunakan metode ini.
sumber
Hanya untuk memperbarui sedikit pertanyaan ini dengan metode Hook baru, Anda cukup menggunakan
useEffect
hook:Juga jika Anda ingin menjalankan sebelum cat tata letak menggunakan
useLayoutEffect
kait:sumber
Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.
saya akan mengedit.Anda dapat mengubah status dan kemudian melakukan perhitungan di callback setState . Menurut dokumentasi Bereaksi, ini "dijamin akan diaktifkan setelah pembaruan diterapkan".
Ini harus dilakukan di
componentDidMount
atau di tempat lain dalam kode (seperti pada event handler ukuran) daripada di konstruktor.Ini adalah alternatif yang baik
window.requestAnimationFrame
dan tidak memiliki masalah yang disebutkan beberapa pengguna di sini (perlu untuk menggabungkannyasetTimeout
atau menyebutnya beberapa kali). Sebagai contoh:sumber
Saya merasa bahwa solusi ini kotor, tetapi kita mulai:
Sekarang saya hanya akan duduk di sini dan menunggu suara turun.
sumber
Bereaksi memiliki beberapa metode siklus hidup yang membantu dalam situasi ini, daftar termasuk tetapi tidak terbatas pada getInitialState, getDefaultProps, componentWillMount, componentDidMount dll.
Dalam kasus Anda dan kasus-kasus yang perlu berinteraksi dengan elemen DOM, Anda harus menunggu sampai dom siap, jadi gunakan componentDidMount seperti di bawah ini:
Juga untuk informasi lebih lanjut tentang siklus hidup dalam reaksi Anda dapat melihat tautan di bawah ini: https://facebook.github.io/react/docs/state-and-lifecycle.html
sumber
Saya mengalami masalah yang sama.
Dalam kebanyakan skenario menggunakan hack-ish
setTimeout(() => { }, 0)
dicomponentDidMount()
bekerja.Tetapi tidak dalam kasus khusus; dan saya tidak ingin menggunakan
ReachDOM findDOMNode
karena dokumentasi mengatakan:(Sumber: findDOMNode )
Jadi dalam komponen tertentu saya harus menggunakan
componentDidUpdate()
acara tersebut, jadi kode saya akhirnya menjadi seperti ini:Lalu:
Akhirnya, dalam kasus saya, saya harus menghapus pendengar yang dibuat di
componentDidMount
:sumber
Setelah render, Anda dapat menentukan ketinggian seperti di bawah ini dan dapat menentukan ketinggian untuk komponen reaksi yang sesuai.
atau Anda dapat menentukan ketinggian masing-masing komponen reaksi menggunakan sass. Tentukan div 2 utama komponen reaksi pertama dengan lebar tetap dan kemudian tinggi komponen utama 3 reaksi dengan otomatis. Jadi berdasarkan konten div ketiga ketinggian akan ditetapkan.
sumber
Saya sebenarnya mengalami masalah dengan perilaku yang serupa, saya membuat elemen video dalam Komponen dengan atribut id itu sehingga ketika RenderDOM.render () mengakhirinya memuat plugin yang memerlukan id untuk menemukan placeholder dan gagal menemukannya.
SetTimeout dengan 0ms di dalam componentDidMount () memperbaikinya :)
sumber
Dari dokumentasi ReactDOM.render () :
sumber
ReactDOM.render
, bukan untuk tingkat komponenReactElement.render
(yang menjadi subjek di sini).Bagi saya, tidak ada kombinasi
window.requestAnimationFrame
atausetTimeout
hasil yang konsisten. Terkadang itu berhasil, tetapi tidak selalu — atau kadang-kadang akan terlambat.Saya memperbaikinya dengan mengulang
window.requestAnimationFrame
sebanyak yang diperlukan.(Biasanya 0 atau 2-3 kali)
Kuncinya adalah
diff > 0
: di sini kita dapat memastikan kapan halaman diperbarui.sumber
Saya punya situasi aneh ketika saya perlu mencetak komponen reaksi yang menerima sejumlah besar data dan melukis di atas kanvas. Saya sudah mencoba semua pendekatan yang disebutkan, tidak ada yang bekerja dengan baik untuk saya, dengan requestAnimationFrame di dalam setTimeout saya mendapatkan kanvas kosong dalam 20% dari waktu, jadi saya melakukan yang berikut:
Pada dasarnya saya membuat rantai requestAnimationFrame's, tidak yakin apakah ini ide yang bagus atau tidak, tetapi ini berfungsi dalam 100% kasus untuk saya sejauh ini (saya menggunakan 30 sebagai nilai untuk variabel n).
sumber
Sebenarnya ada versi yang jauh lebih sederhana dan lebih bersih daripada menggunakan kerangka animasi permintaan atau batas waktu. Iam mengejutkan tidak ada yang membawanya: pawang vanilla-js onload. Jika Anda bisa, gunakan komponen yang melakukan mount, jika tidak, cukup ikat fungsi pada onload hanlder dari komponen jsx. Jika Anda ingin fungsi menjalankan setiap render, jalankan juga sebelum mengembalikan Anda menghasilkan fungsi render. kode akan terlihat seperti ini:
}
sumber
Sedikit pembaruan dengan
ES6
kelas, bukanReact.createClass
Juga - periksa Bereaksi metode siklus hidup komponen: Siklus Hidup Komponen
Setiap komponen memiliki banyak metode yang mirip dengan
componentDidMount
mis.componentWillUnmount()
- komponen akan dihapus dari browser DOMsumber