
JavaScript’in Yürütme Bağlamına Karşı React’in Oluşturma Aşamasında Düşünmek
Bir süredir tepki geliştiricisiyseniz, muhtemelen benimle aynı fikirde olabilirsiniz. kolayca günün arkasındaki en büyük acı haline gelir.
İşte sessiz ama yıkıcı hatalara karşı sizi kontrol altında tutmanıza yardımcı olabilecek bir ipucu: Geri arama işleyicilerinden durum değerlerine başvuran kapanışlardan kaçının.
Doğru yapılırsa, geri arama işleyicilerinde durumla ilgili herhangi bir sorun yaşamamalısınız. Ancak bir noktada hata yaparsanız ve bu, hata ayıklaması zor olan sessiz hatalara yol açarsa, o zaman sonuçlar, gününüzün geri almak istediğiniz o fazladan zamanını yutmaya başlar.
Bununla birlikte, devletle çalışırken bize ortak bir sorunlu senaryo gösterecek olan koddaki bir konuya bakacağız. Önümüzdeki kod örneği bir bileşen gösterecektir App
. Bir ilan edecek collapsed
durum (varsayılan olarak true
) ve bir AppContent
giriş öğesini oluşturan bileşen.
function AppContent({ onChange }) {
const [value, setValue] = React.useState('')
function handleOnChange(e) {
if (onChange) {
onChange(function({ person, collapsed }) {
console.log(collapsed)
console.log(person)
setValue(e.target.value)
})
}
}
return (
<input placeholder="Your value" value={value} onChange={handleOnChange} />
)
}
function App() {
const [collapsed, setCollapsed] = React.useState(true)
function onChange(callback) {
const person = collapsed ? null : { name: 'Mike Gonzalez' }
callback({ person, collapsed })
}
return (
<div>
<AppContent
onChange={(cb) => {
setCollapsed(false)
onChange(cb)
}}
/>
</div>
)
}
Bir kullanıcı bir şey yazdığında, onu arayacaktır. onChange
yönlendirilen sahne işleyicisinden App
. alacak callback
argüman ve ayarlar collapsed
devlet false
böylece çocukları içeriklerini gösterecek şekilde genişleyebilir. Sonra infaz içeride biter handleOnChange
( callback
), geçen collapsed
ve rastgele person
verilerle doldurulmuş değişken (Evet, rastgele biliyorum) Yalnızca collapsed
dır-dir false
.
Kod aslında beklenmeyen konsol hataları olmadan sorunsuz çalışır ve hayat iyidir.
Aslında, bir var ana bu kodda sorun. Konsol hatası olmadan atılmamız ve kodumuzun zaten kırılmaması, onu tehlikeli bir hata haline getiriyor!
biraz ekleyelim console.log
içinde handleOnChange
ve ne elde ettiğimize bakın:
function handleOnChange(e) {
if (onChange) {
onChange(function({ person, collapsed }) {
console.log(`collapsed: ${collapsed}`)
console.log(`person: ${JSON.stringify(person)}`)
setValue(e.target.value)
})
}
}
Bir dakika, neden person
null
ve collapsed
true
? Durum değerini zaten ayarladık collapsed
ile false
ve çalışma zamanı sorunsuz ilerleyebildiğinden bunun geçerli bir JavaScript kodu olduğunu biliyoruz:
return (
<div>
<AppContent
onChange={(cb) => {
setCollapsed(false)
onChange(cb)
}}
/>
</div>
)
JavaScript’teki yürütme bağlamını anlarsanız, bunun bir anlamı yoktur, çünkü çağrıyı içine alan işlev setCollapsed
bitirmişti önceki aramayı yerel birimine gönderme onChange
işlev!
Eh, bu aslında hala doğru. Şu anda JavaScript’in yanlış yaptığı hiçbir şey yok. Aslında tepki işini yapıyor.
Oluşturma sürecinin tam bir açıklaması için onların sayfasına gidebilirsiniz. belgeler.
Ama kısacası, temelde her tepki anında yeni bir işlemek bir aşama alır “enstantane fotoğraf” mevcut olan her şeyin bu işleme aşamasına özel. Reaksiyonun esas olarak ağacı temsil eden bir reaksiyon elementleri ağacı oluşturduğu bir aşamadır. o sırada.
Tanım olarak çağrı setCollapsed
yapmak yeniden oluşturma işlemine neden olur, ancak bu oluşturma aşaması zamanın gelecekteki bir noktasındadır! Bu nedenle collapsed
hala true
ve person
dır-dir null
çünkü o sırada infaz o render için özeldiriçinde yaşadıkları kendi küçük dünyalarına sahip olmak gibi.
JavaScript’te yürütme bağlamı kavramı şöyle görünür:
Bu, örneklerimizdeki tepkinin oluşturma aşamasıdır (Bunu, tepkilerine sahip olmak olarak düşünebilirsiniz. kendi yürütme bağlamı):
Bununla birlikte, çağrımıza bir göz atalım setCollapsed
Yeniden:
Bunların hepsi aynı oluşturma aşamasında oluyor, bu yüzden çökmüş hala true
ve person
olarak geçiliyor null
. Bileşenin tamamı yeniden oluşturulduğunda, sonraki oluşturma aşamasındaki değerler, öncekinden gelen değerleri temsil edecektir: