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

원글 페이지 : 바로가기

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 (

Count: {count}

);
}; .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(); .render() 사용 시 Automatic Batching 적용 단, React 18버전 이상일 경우 이는 적용되지 않는다 // index.js
import React from ‘react’;
import ReactDOM from ‘react-dom’;
import App from ‘./App’;

ReactDOM.render(, 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 (

Count: {count}

);
}; 실제로 확인해 볼 경우 .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

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다