Toplu Güncellemelere Tepki Ver

Tek bir oluşturma çağrısında durum güncellemeleri nasıl birleştirilir

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
}