Kısa cevap:
React, referansların önceden ayarlandığını componentDidMount
veya componentDidUpdate
çengelleri garantiler . Ama sadece gerçekten dönüştürülmüş çocuklar için .
componentDidMount() {
}
componentDidUpdate() {
}
render() {
return <div ref={/* ... */} />;
}
Bu, "React her zaman bu kancalar çalışmadan önce tüm referansları ayarlar" anlamına gelmez .
Ref bazı örneklere atalım yok set olsun.
İşlenmemiş öğeler için referanslar ayarlanmıyor
React, yalnızca render'dan gerçekten döndürdüğünüz öğeler için ref geri aramalarını çağırır .
Bu, kodunuz şöyle görünüyorsa
render() {
if (this.state.isLoading) {
return <h1>Loading</h1>;
}
return <div ref={this._setRef} />;
}
ve başlangıçta this.state.isLoading
olduğu true
sen gerektiğini değil beklemek this._setRef
önce çağrılacak componentDidMount
.
Bu mantıklı olmalıdır: Eğer ilk işleminiz geri döndüyse <h1>Loading</h1>
, React'in başka bir koşulda ref eklenmesini gerektiren başka bir şey döndürdüğünü bilmesinin mümkün bir yolu yoktur. Ayrıca ref'i ayarlayacak hiçbir şey yoktur: yöntem <div>
oluşturulmaması render()
gerektiğini söylediği için öğe yaratılmadı .
Yani bu örnekle sadece componentDidMount
ateş edecek. Ancak, olarak this.state.loading
değiştirildiğindefalse
, this._setRef
önce eklendiğini göreceksiniz ve ardından componentDidUpdate
ateşleyeceksiniz.
Diğer bileşenlere dikkat edin
Not olduğunu ve diğer bileşenler aşağı hakemlerimizle çocukları geçirirseniz onlar önler render (ve soruna neden) o şey yapıyoruz bir şans var.
Örneğin, bu:
<MyPanel>
<div ref={this.setRef} />
</MyPanel>
çıktısına MyPanel
dahil edilmeseydi işe props.children
yaramazdı:
function MyPanel(props) {
return <h1>Oops, no refs for you today!</h1>;
}
Yine, bu bir hata değil: DOM öğesi yaratılmadığı için React'in ref'i ayarlayabileceği hiçbir şey olmayacaktı .
Referanslar, yuvalanmış bir ortama geçirildiyse yaşam döngülerinden önce ayarlanamaz ReactDOM.render()
Önceki bölüme benzer şekilde, bir çocuğu başka bir bileşene ref ile iletirseniz, bu bileşenin ref'in zamanında eklenmesini engelleyen bir şey yapması mümkündür.
Örneğin, belki çocuğu geri getirmiyor render()
ve bunun yerine ReactDOM.render()
bir yaşam döngüsü kancasını arıyor . Bunun bir örneğini burada bulabilirsiniz . Bu örnekte şunları yapıyoruz:
<MyModal>
<div ref={this.setRef} />
</MyModal>
Ama MyModal
bir gerçekleştirir ReactDOM.render()
aramayı onun componentDidUpdate
yaşam döngüsü yöntemiyle:
componentDidUpdate() {
ReactDOM.render(this.props.children, this.targetEl);
}
render() {
return null;
}
React 16'dan beri, bir yaşam döngüsü boyunca bu tür üst düzey render çağrıları, tüm ağaç için yaşam döngüleri çalışana kadar ertelenecektir . Bu, zamanla eklenen referansları neden görmediğinizi açıklar.
Bu sorunun çözümü
, iç içe çağrılar yerine portallar kullanmaktır ReactDOM.render
:
render() {
return ReactDOM.createPortal(this.props.children, this.targetEl);
}
Bu şekilde <div>
ref ile yaptığımız şey aslında render çıktısına dahil edilir.
Bu nedenle, bu sorunla karşılaşırsanız, bileşeniniz ile ref arasında çocukları işlemeyi geciktirebilecek hiçbir şey olmadığını doğrulamanız gerekir.
setState
Referansları saklamak için kullanmayın
setState
Ref içinde ref geri çağrısını saklamak için kullanmadığınızdan emin olun , çünkü eşzamansız olduğu ve "bitmeden" önce componentDidMount
çalıştırılacaktır.
Hâlâ bir Sorun mu?
Yukarıdaki ipuçlarından hiçbiri yardımcı olmazsa, React'te bir sorun bildirin ve bir göz atalım.
this
, sınıfınızın dışındaki sözcük kapsamından değerini yakalayacaktır . Sınıf yöntemleriniz için ok işlevi sözdiziminden kurtulmaya çalışın ve yardımcı olup olmadığına bakın.