한국어

React의 자동 일괄 처리가 여러 상태 업데이트를 최적화하여 애플리케이션 성능을 향상시키고 불필요한 재렌더링을 방지하는 방법을 알아보세요.

React 자동 일괄 처리: 성능을 위한 상태 업데이트 최적화

React의 성능은 부드럽고 반응성이 뛰어난 사용자 인터페이스를 만드는 데 매우 중요합니다. 성능 향상을 위해 도입된 주요 기능 중 하나는 자동 일괄 처리입니다. 이 최적화 기술은 여러 상태 업데이트를 자동으로 단일 재렌더링으로 그룹화하여 상당한 성능 향상을 이끌어냅니다. 이는 상태 변경이 빈번한 복잡한 애플리케이션에서 특히 중요합니다.

React 자동 일괄 처리란 무엇입니까?

React의 맥락에서 일괄 처리는 여러 상태 업데이트를 단일 업데이트로 그룹화하는 프로세스입니다. React 18 이전에는 일괄 처리가 React 이벤트 핸들러 내에서 발생하는 업데이트에만 적용되었습니다. setTimeout, 프로미스 또는 네이티브 이벤트 핸들러 내와 같이 이벤트 핸들러 외부의 업데이트는 일괄 처리되지 않았습니다. 이는 불필요한 재렌더링과 성능 병목 현상으로 이어질 수 있었습니다.

React 18은 자동 일괄 처리를 도입하여 이 최적화를 모든 상태 업데이트로 확장했습니다. 즉, 상태 업데이트가 React 이벤트 핸들러, setTimeout 콜백 또는 프로미스 확인 내에서 발생하는지 여부에 관계없이 React는 자동으로 단일 재렌더링으로 일괄 처리합니다.

자동 일괄 처리가 중요한 이유는 무엇입니까?

자동 일괄 처리는 몇 가지 주요 이점을 제공합니다.

자동 일괄 처리 작동 방식

React는 현재 실행 컨텍스트가 끝날 때까지 상태 업데이트 실행을 지연시켜 자동 일괄 처리를 수행합니다. 이를 통해 React는 해당 컨텍스트 중에 발생한 모든 상태 업데이트를 수집하고 단일 업데이트로 일괄 처리할 수 있습니다.

다음은 단순화된 예입니다.

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>
  );
}

React 18 이전에는 버튼을 클릭하면 setCount1에 대해 하나, setCount2에 대해 하나, 두 번의 재렌더링이 트리거되었습니다. React 18에서 자동 일괄 처리를 사용하면 두 상태 업데이트가 함께 일괄 처리되어 재렌더링이 한 번만 발생합니다.

자동 일괄 처리의 예

1. 비동기 업데이트

API에서 데이터를 가져오는 것과 같은 비동기 작업은 종종 작업이 완료된 후 상태를 업데이트하는 것을 포함합니다. 자동 일괄 처리를 사용하면 이러한 상태 업데이트가 비동기 콜백 내에서 발생하더라도 함께 일괄 처리됩니다.

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>;
}

이 예에서 setDatasetLoading은 모두 비동기 fetchData 함수 내에서 호출됩니다. React는 이러한 업데이트를 함께 일괄 처리하여 데이터가 페치되고 로딩 상태가 업데이트되면 단일 재렌더링을 수행합니다.

2. 프로미스

비동기 업데이트와 유사하게 프로미스는 종종 프로미스가 확인되거나 거부될 때 상태를 업데이트하는 것을 포함합니다. 자동 일괄 처리를 사용하면 이러한 상태 업데이트도 함께 일괄 처리됩니다.

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>;
}

이 경우 성공 시 setResultsetError(null)이 호출되거나 실패 시 setErrorsetResult(null)이 호출됩니다. 관계없이 자동 일괄 처리는 이를 단일 재렌더링으로 결합합니다.

3. 네이티브 이벤트 핸들러

때로는 React의 합성 이벤트 핸들러 대신 네이티브 이벤트 핸들러(예: addEventListener)를 사용해야 할 수 있습니다. 자동 일괄 처리는 이러한 경우에도 작동합니다.

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>;
}

setScrollPosition이 네이티브 이벤트 핸들러 내에서 호출되더라도 React는 여전히 업데이트를 함께 일괄 처리하여 사용자가 스크롤할 때 과도한 재렌더링을 방지합니다.

자동 일괄 처리 해제

드문 경우지만 자동 일괄 처리를 해제할 수 있습니다. 예를 들어, UI가 즉시 업데이트되도록 강제로 동기식 업데이트를 수행할 수 있습니다. React는 이 목적으로 flushSync API를 제공합니다.

참고: flushSync를 사용하는 것은 성능에 부정적인 영향을 미칠 수 있으므로 드물게 수행해야 합니다. 가능한 경우 항상 자동 일괄 처리를 사용하는 것이 좋습니다.

import { flushSync } from 'react-dom';

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

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

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

이 예에서 flushSync는 React가 즉시 상태를 업데이트하고 구성 요소를 다시 렌더링하도록 강제하여 자동 일괄 처리를 우회합니다.

상태 업데이트 최적화를 위한 모범 사례

자동 일괄 처리가 상당한 성능 향상을 제공하지만 상태 업데이트를 최적화하기 위한 모범 사례를 따르는 것이 여전히 중요합니다.

자동 일괄 처리 및 전반적인 고려 사항

핵심 React 성능 최적화인 자동 일괄 처리는 사용자의 위치, 네트워크 속도 또는 장치에 관계없이 애플리케이션에 전반적으로 도움이 됩니다. 그러나 느린 인터넷 연결 또는 성능이 낮은 장치 시나리오에서 그 영향이 더 두드러질 수 있습니다. 국제적인 사용자를 위해 다음 사항을 고려하십시오.

결론

React 자동 일괄 처리는 React 애플리케이션의 성능을 크게 향상시킬 수 있는 강력한 최적화 기술입니다. 여러 상태 업데이트를 단일 재렌더링으로 자동 그룹화함으로써 렌더링 오버헤드를 줄이고 일관성 없는 상태를 방지하며 전 세계 사용자에게 더욱 부드럽고 반응성이 뛰어난 사용자 경험을 제공합니다. 자동 일괄 처리 작동 방식을 이해하고 상태 업데이트 최적화를 위한 모범 사례를 따르면 전 세계 사용자에게 훌륭한 사용자 경험을 제공하는 고성능 React 애플리케이션을 구축할 수 있습니다. React DevTools와 같은 도구를 활용하면 다양한 글로벌 설정에서 애플리케이션의 성능 프로파일을 더욱 개선하고 최적화할 수 있습니다.