Svenska

Lär dig hur Reacts automatiska batchning optimerar flera tillståndsuppdateringar, förbättrar prestanda och förhindrar onödiga omrenderingar. Se exempel och tips.

React automatisk batchning: Optimera tillståndsuppdateringar för prestanda

Reacts prestanda är avgörande för att skapa smidiga och responsiva användargränssnitt. En av de viktigaste funktionerna som introducerats för att förbättra prestanda är automatisk batchning. Denna optimeringsteknik grupperar automatiskt flera tillståndsuppdateringar till en enda omrendering, vilket leder till betydande prestandaförbättringar. Detta är särskilt relevant i komplexa applikationer med frekventa tillståndsförändringar.

Vad är React automatisk batchning?

Batchning, i React-kontexten, är processen att gruppera flera tillståndsuppdateringar till en enda uppdatering. Före React 18 tillämpades batchning endast på uppdateringar som skedde inom Reacts händelsehanterare. Uppdateringar utanför händelsehanterare, såsom de inom setTimeout, promises eller inbyggda händelsehanterare, batchades inte. Detta kunde leda till onödiga omrenderingar och prestandaproblem.

React 18 introducerade automatisk batchning, vilket utökar denna optimering till alla tillståndsuppdateringar, oavsett var de sker. Detta innebär att oavsett om dina tillståndsuppdateringar sker inom en React-händelsehanterare, en setTimeout-callback eller en promise-upplösning, kommer React automatiskt att batcha dem tillsammans till en enda omrendering.

Varför är automatisk batchning viktigt?

Automatisk batchning ger flera viktiga fördelar:

Hur automatisk batchning fungerar

React uppnår automatisk batchning genom att fördröja exekveringen av tillståndsuppdateringar till slutet av den aktuella exekveringskontexten. Detta gör att React kan samla alla tillståndsuppdateringar som skedde under den kontexten och batcha dem tillsammans till en enda uppdatering.

Överväg detta förenklade exempel:

function ExampleComponent() {
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);

  function handleClick() {
    setTimeout(() => {
      setCount1(count1 + 1);
      setCount2(count2 + 1);
    }, 0);
  }

  return (
    <div>
      <p>Count 1: {count1}</p>
      <p>Count 2: {count2}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}

Före React 18 skulle ett klick på knappen utlösa två omrenderingar: en för setCount1 och en annan för setCount2. Med automatisk batchning i React 18 batchas båda tillståndsuppdateringarna tillsammans, vilket resulterar i endast en omrendering.

Exempel på automatisk batchning i praktiken

1. Asynkrona uppdateringar

Asynkrona operationer, som att hämta data från ett API, involverar ofta att uppdatera tillståndet efter att operationen har slutförts. Automatisk batchning säkerställer att dessa tillståndsuppdateringar batchas tillsammans, även om de sker inom den asynkrona callbacken.

function DataFetchingComponent() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data');
        const jsonData = await response.json();
        setData(jsonData);
        setLoading(false);
      } catch (error) {
        console.error('Error fetching data:', error);
        setLoading(false);
      }
    }

    fetchData();
  }, []);

  if (loading) {
    return <p>Loading...</p>;
  }

  return <div>Data: {JSON.stringify(data)}</div>;
}

I detta exempel anropas både setData och setLoading inom den asynkrona fetchData-funktionen. React kommer att batcha dessa uppdateringar tillsammans, vilket resulterar i en enda omrendering när datan har hämtats och laddningsstatusen har uppdaterats.

2. Promises

I likhet med asynkrona uppdateringar involverar promises ofta att uppdatera tillståndet när promis-en löses eller avvisas. Automatisk batchning säkerställer att även dessa tillståndsuppdateringar batchas tillsammans.

function PromiseComponent() {
  const [result, setResult] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const myPromise = new Promise((resolve, reject) => {
      setTimeout(() => {
        const success = Math.random() > 0.5;
        if (success) {
          resolve('Promise resolved!');
        } else {
          reject('Promise rejected!');
        }
      }, 1000);
    });

    myPromise
      .then((value) => {
        setResult(value);
        setError(null);
      })
      .catch((err) => {
        setError(err);
        setResult(null);
      });
  }, []);

  if (error) {
    return <p>Error: {error}</p>;
  }

  if (result) {
    return <p>Result: {result}</p>;
  }

  return <p>Loading...</p>;
}

I detta fall anropas antingen setResult och setError(null) vid framgång eller setError och setResult(null) vid misslyckande. Oavsett kommer automatisk batchning att kombinera dessa till en enda omrendering.

3. Inbyggda händelsehanterare

Ibland kan du behöva använda inbyggda händelsehanterare (t.ex. addEventListener) istället för Reacts syntetiska händelsehanterare. Automatisk batchning fungerar även i dessa fall.

function NativeEventHandlerComponent() {
  const [scrollPosition, setScrollPosition] = useState(0);

  useEffect(() => {
    function handleScroll() {
      setScrollPosition(window.scrollY);
    }

    window.addEventListener('scroll', handleScroll);

    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []);

  return <p>Scroll Position: {scrollPosition}</p>;
}

Även om setScrollPosition anropas inom en inbyggd händelsehanterare, kommer React fortfarande att batcha uppdateringarna tillsammans, vilket förhindrar överdrivna omrenderingar när användaren scrollar.

Välja bort automatisk batchning

I sällsynta fall kan du vilja välja bort automatisk batchning. Till exempel kanske du vill tvinga en synkron uppdatering för att säkerställa att användargränssnittet uppdateras omedelbart. React tillhandahåller flushSync API för detta ändamål.

Obs: Användning av flushSync bör göras sparsamt, eftersom det kan påverka prestandan negativt. Det är generellt bäst att förlita sig på automatisk batchning när det är möjligt.

import { flushSync } from 'react-dom';

function ExampleComponent() {
  const [count, setCount] = useState(0);

  function handleClick() {
    flushSync(() => {
      setCount(count + 1);
    });
  }

  return (<button onClick={handleClick}>Increment</button>);
}

I detta exempel tvingar flushSync React att omedelbart uppdatera tillståndet och rendera om komponenten, vilket kringgår automatisk batchning.

Bästa praxis för att optimera tillståndsuppdateringar

Även om automatisk batchning ger betydande prestandaförbättringar är det fortfarande viktigt att följa bästa praxis för att optimera tillståndsuppdateringar:

Automatisk batchning och globala överväganden

Automatisk batchning, som är en central prestandaoptimering i React, gynnar applikationer globalt oavsett användarens plats, nätverkshastighet eller enhet. Dess inverkan kan dock vara mer märkbar i scenarier med långsammare internetanslutningar eller mindre kraftfulla enheter. För internationella publiker, överväg dessa punkter:

Slutsats

Reacts automatiska batchning är en kraftfull optimeringsteknik som avsevärt kan förbättra prestandan i dina React-applikationer. Genom att automatiskt gruppera flera tillståndsuppdateringar till en enda omrendering minskar den renderingskostnaden, förhindrar inkonsekventa tillstånd och leder till en smidigare och mer responsiv användarupplevelse. Genom att förstå hur automatisk batchning fungerar och följa bästa praxis för att optimera tillståndsuppdateringar kan du bygga högpresterande React-applikationer som levererar en utmärkt användarupplevelse till användare över hela världen. Att utnyttja verktyg som React DevTools hjälper till att ytterligare förfina och optimera din applikations prestandaprofiler i olika globala miljöer.