React-Redux에서 한 번에 여러 액션을 Dispatch할 때 batch 사용의 필요성

Date
2021/06/24
Tags
Frontend
JavaScript
React
Created by
React-Redux v7.0.0부터 batch() API를 제공한다. 어떤 경우에 사용해야 할까?
Table of Contents

React의 unstable_batchedUpdates()

먼저 React의 unstable_batchedUpdates()라는 API에 대해 알아보자.
unstable_batchedUpdates()는 ReactDOM 및 React Native에 포함된 API로, React core에 포함된 API는 아니다. 이 API는 React 내부적으로 하나의 이벤트 핸들러 내에 포함된 여러 상태 변화를 한 번의 렌더링(single render pass)로 묶어서 일괄 처리하도록 해 준다.
React 내부적으로 이미 이 API가 사용되고 있다. 코드를 통해 어떻게 사용되고 있는지 알아보자.
가령 다음과 같은 간단한 React Component가 있다고 해 보자.
import React, { useEffect, useState } from "react"; export default function App() { const [x, setX] = useState<number>(0); const [y, setY] = useState<number>(0); const handleButtonClick: VoidFunction = () => { setX((s: number) => s + 1); setY((s: number) => s + 1); setY((s: number) => s + 1); }; console.log(`Component rerendered!`); return ( <div> <p> x: {x}, y: {y} </p> <button onClick={handleButtonClick}> This button increases x by 1, y by 2 </button> </div> ); }
TypeScript
복사
버튼을 누르면 x는 1씩, y는 2씩 증가시키는 간단한 컴포넌트이다. 그리고 컴포넌트가 리렌더링될 때마다 이를 알 수 있도록 콘솔에 로그가 찍히게 해 봤다.
위 코드에서 버튼을 누르면 컴포넌트는 몇 번 렌더링될까? 위에서도 설명했듯 React는 내부적으로 DOM에 unstable_batchedUpdates() API를 적용하므로 하나의 이벤트 핸들러 내에서 몇 번의 상태 변화가 일어나든 이를 한 번의 렌더링으로 처리한다. 따라서 버튼을 한 번 누를 때마다 렌더링이 한 번 일어난다.
위의 코드는 https://codesandbox.io/s/unstablebatchedupdatesdemo-25fd9?file=/src/App.tsx에서 직접 확인해볼 수 있다.

React-Redux의 batch()

React-Redux에 존재하는 batch()는 위에서 소개한 unstable_batchedUpdates()의 Redux 버전이라고 생각하면 된다. 앞서 소개한 API의 경우 ReactDOM과 React Native에서만 적용되는 개념이므로, batch()는 React-Redux에서 여러 상태 변화(곧 액션 dispatch)를 하나의 렌더링으로 처리하기 위해 자체적으로 만든 API라고 보면 된다.
import { batch } from 'react-redux' function myThunk() { return (dispatch, getState) => { // should only result in one combined re-render, not two batch(() => { dispatch(increment()) dispatch(increment()) }) } }
TypeScript
복사
공식 문서의 코드와 주석만 봐도 알 수 있듯이, batch() 내에 전달된 함수에서 발생하는 여러 상태 변화들은 모두 하나의 컴포넌트 렌더링으로 처리된다. 이를 적절히 사용하여 React-Redux에서도 불필요한 렌더 함수 호출을 줄일 수 있다.

References