티스토리 뷰
Batching
state가 변경되면 React에서는 렌더링을 하죠? React에서는 불필요한 리렌더링을 방지하기 위해 state를 변경하는 작업을 일괄적으로 처리합니다. 예를 들어 prev+1을 5번 동시에 작성했다면, 1 2 3 4 5가 아니라 그냥 5 이렇게 됩니다.
→ 이렇게 state의 업데이트 작업을 일괄 처리하는 방식을 Batching이라고 합니다. 덕분에 불필요한 리렌더링을 방지할 수 있는 것입니다.
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
function increaseCountThree() {
// 아래의 작업은 모두 일괄적으로 묶여 처리된다. 한 번의 리렌더링만 발생한다.
setCount((prev) => prev + 1);
setCount((prev) => prev + 1);
setCount((prev) => prev + 1);
}
return (
<div>
<button onClick={increaseCountThree}>+1</button>
<p>Count : {count}</p>
</div>
);
}
export default Counter;
실제로 테스트를 해보았더니 위와 같이 딱 한번만 렌더링이 되었습니다. React는 여러 번의 상태 업데이트 작업을 큐(Queue)에 몰아넣고 일정 주기마다 큐에 등록된 작업을 순차적으로 일괄 시행하면서 불필요한 리렌더링을 방지합니다.
React18에서 추가된 Automatic Batching
React18 버전 이하에서는 오직 React의 이벤트 핸들러 내부의 상태 업데이트 작업에 대해서만 Batching이 가능했는데요. 즉, Promise나 setTimeout 등의 내부 작업에는 일괄 처리가 불가능했다는 말입니다.
React18 버전부터는 다양한 작업에 대해서도 Batching 작업이 자동으로 수행됩니다. `ReactDOM.createRoot` 메서드를 기반으로 렌더링을 진행할 경우 모든 상태 업데이트 작업은 자동으로 batching 처리가 됩니다.
→ 바로 이 기능을 Automatic Batching !
참고로, `createRoot`는 이미 CRA를 통해 생성되는 `index.js`파일에 이미 포함되어 있어서, 작성하는 모든 작업에서 automatic batching이 적용된다고 보면 되겠습니다.
📜 index.js 파일
import { createRoot } from 'react-dom/client';
const domNode = document.getElementById('root');
const root = createRoot(domNode);
Automatic Batching을 무시하고 싶을 때는.. (권장 X)
react-dom 라이브러리에 추가된 `ReactDOM.flushSync()` 메서드는 Automatic batching을 무시하고 즉시 DOM을 렌더링해줍니다. React에서는 공식적으로 해당 메서드의 사용을 추천하진 않으며, 필요한 상황이 있을 경우에만 사용할 것을 강조했습니다.
import { flushSync } from "react-dom";
function handleClick() {
// React 는 flushSync 메서드가 실행되는 즉시 DOM을 업데이트 한다.
flushSync(() => {
setCounter((c) => c + 1);
});
// React 는 flushSync 메서드가 실행되는 즉시 DOM을 업데이트 한다.
flushSync(() => {
setFlag((f) => !f);
});
// 따라서 해당 함수가 실행될 경우 React는 총 두 번의 리렌더링을 수행한다.
}
참고문서
'프론트엔드 > React' 카테고리의 다른 글
[React] 쓸 줄만 알았던 react-router-dom v6 동작원리 (0) | 2023.06.21 |
---|---|
[React] React Testing Library과 관련된 일반적인 실수 (0) | 2023.06.15 |
[React] Lazy loading과 Code splitting - 적당히 적당히 가져오자 (0) | 2023.06.13 |
[React] Virtual DOM과 ✨React 렌더링 동작 원리✨ with Fiber (2) | 2023.06.12 |
[React] RTL의 screen 객체가 가진 쿼리 메서드(query Methods) (0) | 2023.06.07 |
- Total
- Today
- Yesterday
- react
- 파이썬
- 인프런
- rtl
- 자바스크립트 기초
- 딥러닝
- 리액트
- HTML
- 스타일 컴포넌트 styled-components
- styled-components
- react-query
- TypeScript
- 타입스크립트
- 프론트엔드 공부
- 리액트 훅
- 프론트엔드
- testing
- 머신러닝
- CSS
- 프론트엔드 기초
- 자바스크립트
- 프로젝트 회고
- next.js
- 자바
- 디프만
- 데이터분석
- Python
- frontend
- JSP
- jest
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |