React üzerinde çalışıyorum.
TLDR:
Ancak React'in durumu setState ile aynı sırada güncellemesi için güvenebilir misiniz?
Evet.
Evet.
Sipariş güncellemeleri her zaman saygı duyulur. "Aralarında" bir ara durum görüp görmediğiniz, bir grup içinde olup olmadığınıza bağlıdır.
Şu anda (React 16 ve öncesi), yalnızca React olay işleyicileri içindeki güncellemeler varsayılan olarak toplu olarak işlenmektedir . İhtiyaç duyduğunuz nadir durumlarda olay işleyicilerinin dışında toplu işlem yapmaya zorlamak için kararsız bir API vardır.
Gelecek sürümlerde (muhtemelen React 17 ve sonrası), React tüm güncellemeleri varsayılan olarak toplu olarak işleyecektir, böylece bunu düşünmek zorunda kalmazsınız. Her zaman olduğu gibi, bu konudaki değişiklikleri React blogunda ve sürüm notlarında duyuracağız .
Bunu anlamanın anahtarı, bir React olay işleyicisinde kaç bileşende kaç tane setState()
çağırırsanız çağırın, olay sonunda yalnızca tek bir yeniden işleme üretecekleridir . Çünkü eğer Bu büyük uygulamalarda iyi performans için çok önemlidir Child
ve Parent
her çağrı setState()
bir tıklama olayını ele, sen yeniden işlemek istemiyorum Child
iki kez.
Her iki örneğinizde de setState()
çağrılar bir React olay işleyicisinin içinde gerçekleşir. Bu nedenle, olayın sonunda her zaman birlikte yıkanırlar (ve ara durumu görmezsiniz).
Güncellemeler, oluştukları sıraya göre her zaman yüzeysel olarak birleştirilir . Dolayısıyla, ilk güncelleme ise {a: 10}
, ikincisi {b: 20}
ve üçüncüsü ise {a: 30}
, işlenmiş durum olacaktır {a: 30, b: 20}
. Aynı durum anahtarına yapılan daha yeni güncelleme (örneğin a
benim örneğimdeki gibi ) her zaman "kazanır".
this.state
Nesne ne zaman toplu sonunda UI yeniden işlemek güncellenir. Bu nedenle, durumu önceki bir duruma göre güncellemeniz gerekiyorsa (bir sayacı artırmak gibi), setState(fn)
okumak yerine size önceki durumu veren işlevsel sürümü kullanmalısınız this.state
. Bunun gerekçesini merak ediyorsanız , bu yorumda derinlemesine anlattım .
Örneğinizde, "ara durumu" görmeyiz çünkü toplu işlemin etkinleştirildiği bir React olay işleyicisinin içindeyiz (çünkü React o olaydan ne zaman çıktığımızı "bilir").
Bununla birlikte, hem React 16 hem de önceki sürümlerde, henüz React olay işleyicilerinin dışında varsayılan olarak gruplama yoktur . Dolayısıyla, örneğinizde bunun yerine bir AJAX yanıt işleyicimiz olsaydı handleClick
, her biri setState()
olur olmaz işlenirdi. Bu durumda, evet, olur bir ara devlet bkz:
promise.then(() => {
// We're not in an event handler, so these are flushed separately.
this.setState({a: true}); // Re-renders with {a: true, b: false }
this.setState({b: true}); // Re-renders with {a: true, b: true }
this.props.setParentState(); // Re-renders the parent
});
Bir olay işleyicide olup olmamanıza bağlı olarak davranışın farklı olmasının uygunsuz olduğunun farkındayız . Bu, tüm güncellemeleri varsayılan olarak toplu hale getirecek (ve değişiklikleri eşzamanlı olarak temizlemek için bir katılım API'si sağlayacak) gelecekteki bir React sürümünde değişecektir. Varsayılan davranışı değiştirene kadar (potansiyel olarak React 17'de), gruplamayı zorlamak için kullanabileceğiniz bir API vardır :
promise.then(() => {
// Forces batching
ReactDOM.unstable_batchedUpdates(() => {
this.setState({a: true}); // Doesn't re-render yet
this.setState({b: true}); // Doesn't re-render yet
this.props.setParentState(); // Doesn't re-render yet
});
// When we exit unstable_batchedUpdates, re-renders once
});
Dahili olarak React olay işleyicilerinin tümü sarmalanmaktadır, unstable_batchedUpdates
bu yüzden varsayılan olarak toplu olarak işlenirler. Bir güncellemeyi unstable_batchedUpdates
iki kez sarmanın bir etkisi olmadığını unutmayın. En dıştaki unstable_batchedUpdates
aramadan çıktığımızda güncellemeler temizlenir .
Bu API, toplu işleme varsayılan olarak zaten etkinleştirildiğinde onu kaldıracağımız anlamında "kararsız" dır. Ancak, onu küçük bir sürümde kaldırmayacağız, bu nedenle React olay işleyicileri dışındaki bazı durumlarda gruplamayı zorlamanız gerekirse, React 17'ye kadar güvenle güvenebilirsiniz.
Özetlemek gerekirse, bu kafa karıştırıcı bir konudur çünkü varsayılan olarak yalnızca olay işleyicileri içindeki react gruplarıdır. Bu, gelecekteki sürümlerde değişecek ve o zaman davranış daha kolay olacaktır. Ancak çözüm, daha az parti yapmak değil , varsayılan olarak daha fazla parti yapmaktır. Yapacağımız şey bu.