[Automatic Batching] 리액트 18에 등장한 렌더링 묶음판매

2023. 10. 6. 21:44·Development Study/Frontend
728x90

Automatic Batching이란 무엇일까?

[[React]] 18에서 나온 새로운 기능, Automatic Batching에 대한 문서이다

여기서 Batching이란, 이벤트 핸들러나 hooks 안에서 상태 업데이트를 묶어서 동작하도록 만들어준다. 즉, 렌더링을 한 번만 일어나도록 해주는 것이다

따라서 Automatic Batching = 자동화된 일괄 렌더링 이라고 생각할 수 있다

사실 생각해보면 이상하다. 기존의 함수 내부에서 여러 setState()를 실행시키면 이미 Batching이 이루어졌을까?

  • 그 이유는 React에는 여러 번의 state update 작업을 Queue에 몰아넣고 일정 주기마다 Queue에 등록된 작업을 순차적으로 일괄 시행하면서 불필요한 리렌더링을 방지하는 특징이 있기 때문이다

코드를 통해 확인해보자

이전에는 batching 이 각각의 React event 마다 한 번씩 이루어졌었다

// Before: only React events were batched.
setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will render twice, once for each state update (no batching)
}, 1000);

결국 위 코드에서는 각각의 이벤트들마다 렌더링이 되므로, 두 번 렌더링 되었다

  • setCount()에서 한 번
  • setFlag()에서 한 번 더

이는 불필요한 렌더링을 야기한다는 점에서 문제를 일으킨다

기존(~React 17)에는 오직 React의 이벤트 핸들러 내부의 state update 작업에 대해서만 batching이 가능했다. 이 말은 Promise, setTImeout, native event handler 내부의 작업은 불가능했었다

React 18버전으로 넘어가면서 리액트 이벤트 핸들러 내부 뿐만 아니라 promises, setTimeout, 여러 native event handler 안에서도 배칭이 적용된다

// After: updates inside of timeouts, promises,
// native event handlers or any other event are batched.
setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will only re-render once at the end (that's batching!)
}, 1000);

이렇게 되면 setTimeout() 안에있는 내용들에 Automatic Batching이 적용되면서 렌더링을 한번만 발생시킨다

발동조건

하지만 언제나 이렇게 되는 것은 아니라는 것을 주의해야 한다

  • .createRoot() method 를 사용했을때만 automatic batching이 적용된다
  • 만약 이전 레거시인 .render() method 를 사용할 경우 React 18이어도 적용되지 않는다

이 설정을 적용해서 사용하려면?
App.js 와 이를 설정하는 index.js 두 파일로 설명을 해보겠다

App.js

import React from 'react';

export default function App() {
  const [count, setCount] = React.useState(0);

  const handleClick = () => {
    setCount(prev => prev + 1);
    setCount(prev => prev + 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increase Twice</button>
    </div>
  );
};

.createRoot() 사용 시 Automatic Batching 적용

추가로 [[React Concurrent Mode]]의 기능을 활용할 수 있다

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

const root = document.getElementById('root');
const reactRoot = ReactDOM.createRoot(root);
reactRoot.render(<App />);

.render() 사용 시 Automatic Batching 적용

단, React 18버전 이상일 경우 이는 적용되지 않는다

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

+ 만약 Automatic Batching을 무시해야 하는 상황이라면?

react-dom 라이브러리에 추가된 ReactDOM.flushSync() 메서드를 사용한다

  • 단, React에서는 공식적으로 해당 메서드의 사용을 추천하지는 않는다
    • 필요한 상황이 있을 경우에만 사용할 것을 권장하고 있다

아래에는 이 메서드를 활용한 렌더링 확인용 Counter와 렌더링이 될 때마다 로그를 찍도록 하는 간단한 예제를 만들어보았다

// App.js
import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';

export default function App() {
  const [count, setCount] = React.useState(0);

  const handleClick = () => {
    ReactDOM.flushSync(() => { // 여기서 첫 렌더링
      setCount(prev => prev + 1);
    });
    setCount(prev => prev + 1); // 이 이후 일괄 적용 렌더링
    setCount(prev => prev + 1);
  };

  useEffect(() => {
    console.log('Component rendered with count:', count);
  });

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increase Thrice</button>
    </div>
  );
};

실제로 확인해 볼 경우 .flushSync() 가 적용되어있는 경우에는 두 번씩 렌더링되며, 이 메서드를 빼고 확인해볼 경우에 한 번씩 렌더링되는 것을 볼 수 있다!

 

위의 코드처럼 .flushSync()를 적용하자 15부터 2번씩 렌더링되는 모습을 볼 수 있다


References

  • https://react.dev/blog/2022/03/29/react-v18
  • https://velog.io/@dbwjd5864/React-18-automatic-batching%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90#:~:text=automatic%20batching%2C%20%EC%9E%90%EB%8F%99%20%EB%B0%B0%EC%B9%AD%EC%9D%B4%EB%9E%80,%EC%95%88%EC%97%90%EC%84%9C%EB%8F%84%20%EB%B0%B0%EC%B9%AD%EC%9D%B4%20%EC%A0%81%EC%9A%A9%EB%90%9C%EB%8B%A4.
  • https://velog.io/@rookieand/React-18%EC%97%90%EC%84%9C-%EC%B6%94%EA%B0%80%EB%90%9C-Auto-Batching-%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80
728x90
저작자표시 비영리 변경금지 (새창열림)

'Development Study > Frontend' 카테고리의 다른 글

<Jest, Unit Test> 쉽고 빠르게 단위테스트 알아보기  (0) 2023.11.13
[JavaScript] class는 교실이 아니라 객체이다  (1) 2023.10.27
UI 버벅임은 이제 그만! Web Worker 를 적절히 이용하여 UX 증진시키기  (0) 2023.10.06
[NextJS AppRouter] 초간단 API Mocking 하기(with Route Handlers)  (0) 2023.09.28
클라이언트까지 꼭 데이터가 와야할까? RCS(React Server Components)에 대해 알아보자  (0) 2023.09.28
'Development Study/Frontend' 카테고리의 다른 글
  • <Jest, Unit Test> 쉽고 빠르게 단위테스트 알아보기
  • [JavaScript] class는 교실이 아니라 객체이다
  • UI 버벅임은 이제 그만! Web Worker 를 적절히 이용하여 UX 증진시키기
  • [NextJS AppRouter] 초간단 API Mocking 하기(with Route Handlers)
ThreeLight
ThreeLight
ThreeLight Studio의 블로그, TimeMap.exe에 오신 것을 환영합니다.
  • ThreeLight
    TimeMap.exe
    ThreeLight
  • 전체
    오늘
    어제
    • 분류 전체보기 (245)
      • Checkpoint (1)
      • (3D)Dev Deep Dive (0)
        • Templates & Guides (9)
        • Frontend origin (9)
        • Backend origin (1)
        • TroubleShootings (4)
      • Development Study (95)
        • Frontend (36)
        • Backend (21)
        • CS(Computer Science) (2)
        • Background Knowledges (11)
        • Algorithm (2)
        • Mobile (3)
        • AWS (6)
        • Python (6)
        • MSW(MapleStoryWorlds) (8)
      • Coding Test (59)
        • 문제.zip (1)
        • BaekJoon_JavaScript (0)
        • Programmers_JavaScript (9)
        • BaekJoon_Python (23)
        • Programmers_Python (10)
        • Undefined_Python (3)
        • Programmers_SQL (13)
      • 활동내역.zip (43)
        • 개인 (21)
        • Techeer (12)
        • Bootcamp (7)
        • Hackathon (1)
        • TeamProjects (2)
      • 여기 괜찮네??(사이트 | App) (5)
      • 재미있는 주제들 (8)
      • 개발 외 공부 저장소 (11)
        • 생산운영관리 (3)
        • 생활속의금융 (6)
        • 경영정보시스템 (2)
  • 링크

    • TimeMap.dmg (Portfolio)
    • GitHub 바로가기
    • 오픈프로필(카카오톡)
    • Medium 바로가기
    • Disquiet 바로가기
    • LinkedIn 바로가기
  • 인기 글

  • 태그

    HTML
    JavaScript
    SQL
    programmers
    Python
    프로그래머스
    react
    CSS
    Baek Joon
    TypeScript
  • 최근 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.1
ThreeLight
[Automatic Batching] 리액트 18에 등장한 렌더링 묶음판매
상단으로

티스토리툴바