React.js toplu güncellemeleri
Bir bileşenin durumunu her güncellediğinizde, React'in farklılaştırma algoritmasının sanal DOM'deki değişiklikleri algılayacağını ve bileşeninizi gerçek DOM'da oluşturacağını zaten biliyorsunuz. Ancak bu gerçekten her durum güncellemesi için mi oluyor? Veya React, birden çok durum mutasyonunun tek bir oluşturma çağrısında birleştirilmesi için bu güncellemeleri toplulaştırmanın bir yolunu sunuyor mu?
Sentetik olaylar, toplu güncellemelere izin verir
React 17 ve altı, bu güncellemeleri toplu hale getirmek için bir mekanizma sağlar. Kod yazarken gerçekten çok fazla düşünmenize gerek yok, ancak React'in kodunuzu nasıl optimize edebileceğini bilmek yine de harika bir öğrenmedir.
İşte neler oluyor.
- çoklu durum mutasyonları bir geri arama içinde çağrılır
- geri arama sentetik bir olaya bağlıysa, React bu mutasyonları gruplayacaktır.
- mutasyonlar gruplandırıldığında, yalnızca tek bir oluşturma çağrısı yapılır
- aksi takdirde, her mutasyon yeni bir işlemeye yol açar
Toplu işleme izin vermek için, durum mutasyonlarınızın sentetik bir React-olay içinde çağrılması gerekir. Hızlı bir hatırlatma olarak, sentetik React olayları temel olarak tüm tarayıcılarda aynı işlevselliği sağlamak için yerel HTML olaylarının etrafındaki bir sarmalayıcıdır. Her sentetik olay işleyicisi, doğrudan bir bileşene prop olarak sağlanabilir.
Her şeyi çalışırken görmek için, React'in mutasyon başına bir oluşturma yerine tüm durum mutasyonlarını tek bir oluşturmada birleştirmesine olanak tanıyan bir örnek kod.
function Component() {
const [id, setId] = useState(0);
const [date, setDate] = useState(new Date());
const [random, setRandom] = useState(Math.random());
// A lame callback, but it's just for
// the demo. Note that clicking on the
// button will only lead to a single
// re-render!
//
// This is b/c the callback is provided to
// 'onClick', a synthetic event.
const onButtonClick = () => {
setDate(new Date());
setId(prevId => prevId + 1);
}
console.log("Render:", id, date);
return (
<div>
<button
onClick={onButtonClick}>
Update state
</button>
</div>
);
}
//
// Almost the same as the previous
// example, but this time w/o
// a batched upate call.
//
function Component() {
const [id, setId] = useState(0);
const [date, setDate] = useState(new Date());
const [random, setRandom] = useState(Math.random());
// No batching, as the state
// mutations happend inside
// a setTimeout - even though
// the timeout is inside a
// synthetic event.
const onButtonClick = () => {
setTimeout(() => {
setDate(new Date());
setId(prevId => prevId + 1);
}, 0);
}
console.log("Render:", id, date);
return (
<div>
<button
onClick={onButtonClick}>
Update state
</button>
</div>
);
}
React 18 ve sonrası için toplu güncellemeler
React'in bir sonraki sürümüyle (en azından ben bunu yazarken), harmanlama mekanizması çok daha iyileştirilmiş olacak. Yalnızca sentetik olaylarda mümkün olmak yerine, diğer geri arama türleri de kullanılabilir olacaktır.
- zaman aşımları
- vaatler
- yerel olay işleyicileri
Otomatik olarak daha az oluşturma gerçekleştirileceğinden, bu değişiklik büyük olasılıkla uygulamanızın daha iyi performans göstermesine yol açacaktır.
React 18 ve sonraki sürümlerde toplu güncellemelerden kaçınma
React 18'den başlayarak, her durum mutasyonuyla açıkça yeni bir oluşturmayı tetikleme seçeneğine sahip olacaksınız, bu nedenle toplu güncellemelerden kaçınacaksınız. Bu büyük olasılıkla yalnızca uç durumlarda kullanılacaktır, ancak yine de bilmek ilginçtir.
//
// This example is almost
// 1:1 from Dan Abramov's
// example.
//
// Use 'flushSync' from the
// 'react-dom'-package.
import { flushSync } from 'react-dom';
function handleClick() {
flushSync(() => {
setId(prevId => prevId + 1);
});
// React has updated the DOM by now
flushSync(() => {
setDate(new Date());
});
// React has updated the DOM by now
}