[TIL]2023.06.20 리액트의 배치 처리

Nick·2023년 6월 23일
0

TIL: 오늘을 돌아보자

목록 보기
28/95
post-thumbnail
post-custom-banner

리액트의 배치(batch) 처리

import { useState } from "react";
import "./App.css";

function App() {
  const [num, setNum] = useState(0);
  return (
    <>
      <div>Number State: {num}</div>
      <button
        onClick={() => {
          setNum(num + 1);
          setNum(num + 1);
          setNum(num + 1);
        }}>
        누르면 up
      </button>
    </>
  );
}

export default App;


import { useState } from "react";
import "./App.css";

function App() {
  const [num, setNum] = useState(0);
  return (
    <>
      <div>Number State: {num}</div>
      <button
        onClick={() => {
          setNum((curNum) => curNum + 1);
          setNum((curNum) => curNum + 1);
          setNum((curNum) => curNum + 1);
        }}>
        누르면 up
      </button>
    </>
  );
}

export default App;

위 두 코드의 차이

  • 첫 번째 코드는 버튼을 클릭했을 때 1만 올라가지만 두 번째 코드는 3씩 올라간다

"강의를 듣고 잘못 이해한 내용"

  • 함수형 업데이트 방식은 배치 업데이트 방식이 아니라 명령들을 한 번씩 순차적으로 실행하는 방식
    (함수 업데이트 방식을 사용하면 배치 업데이트 방식을 사용하지 않는다)

"재적립한 내용"

함수형 업데이트 방식도 배치 처리를 한다.

리액트는 return이 끝나면 예약한 state 변경사항들의 처리 결과를 마지막에 한 번 반영한다.
state는 return이 끝나기 전 state의 변경 값들의 히스토리가 있다.(각각의 처리 결과들을 저장한다)

첫 번째 코드에서 setNum(num + 1)의 num은 setState가 반영되기 전(리렌더링 되기 전), 즉 0이기 때문에 몇 번을 작성해도 값은 0으로 동일함 => 마지막에 0 + 1 값을 반영한다.

setNum(num + 1); // num값: 0 => 0 + 1
setNum(num + 1); // num값: 0 => 0 + 1
setNum(num + 1); // num값: 0 => 0 + 1
// 0 -> 0 + 1 -> 0 + 1 -> 0 + 1

두 번째 코드에서 setNum((curNum) => curNum + 1)은 curNum(현재 state값)을 받아서 + 1을 한 값을 리턴한다

setNum((curNum) => curNum + 1); // 현재 state값:0 => 0 + 1 => state값: 1
setNum((curNum) => curNum + 1); // 현재 state값:1 => 1 + 1 => state값: 2
setNum((curNum) => curNum + 1); // 현재 state값:2 => 2 + 1 => state값: 3
// 0 -> 0 + 1 -> (0 + 1) + 1 -> ((0 + 1) + 1) + 1

이후 return이 끝나면 변경사항을 반영한다 -> state가 3이 됨 -> state가 변경됐으니 리렌더링

만약 이러한 코드가 있다고 할 때

import { useState, useEffect } from "react";
import "./App.css";

function App() {
 const [num, setNum] = useState(0);
 useEffect(() => {
   console.log("hi");
 }, [num]);
 
 return (
   <div>
     <button
       onClick={() => {
         setNum((curNum) => curNum + 1);
         setNum(1);
         setNum((curNum) => curNum + 1);
       }}>
       up
     </button>
   </div>
 );
}

export default App;

버튼을 클릭하면 아래 과정이 된다.

setNum((curNum) => curNum + 1); // 현재 state값: 0 => 0 + 1
setNum(1);                      // 현재 state값을 1로 할당
setNum((curNum) => curNum + 1); // 현재 state값: 1 => 1 + 1
// 처음 버튼 클릭하면 0 -> 0 + 1 -> 1 -> 1 + 1
// 이후 버튼 클릭하면 2 -> 2 + 1 -> 1 -> 1 + 1   반복

따라서 useEffect에 있는 console.log는 초기 렌더링시 1번, 처음 버튼 클릭시 1번 출력되고 이후 버튼을 클릭해도 state는 계속 2라 변경사항이 없어서 출력되지 않는다.

결국 함수형 업데이트 방식을 사용해도 리액트는 배치 처리를 하며,

해당 state의 제일 마지막 결괏값을 return이후 state의 변경사항으로 한 번 처리하고 리렌더링 여부를 결정한다.

profile
배우고 도전하는것을 멈추지 않는 개발자 입니다.
post-custom-banner

0개의 댓글