React의 setState가 비동기 처리되는 이유

Seongkyun Yu·2020년 12월 9일
7

TIL - React

목록 보기
3/4

1. 상태 관리의 비동기성

React를 공부할 때 중요하게 배우는 개념 중 하나는 상태관리다.

React는 상태를 바탕으로 View를 그리기 때문에 일반 변수로 사용하지 않고 setState로 상태를 할당한다고 배운다.

하지만 JavaScript를 공부할 때 처럼 console.log로 상태 변화를 확인하려 하면 이상한 점을 느끼게 된다.

그 이상함(console.log의 결과값이 이전 상태를 나타냄)은 setState가 비동기적으로 처리되기 때문인데 어째서 React는 상태 변화를 비동기적으로 관리하는지 정리해보겠다.


2. 흔히 하는 실수

많이들 하는 실수인데, 상태를 처음 접하면 많이들 아래와 같은 코드로 변경된 상태를 확인하려한다.

import React, { useState } from "react";

function App() {
  const [state, setState] = useState(1);

  const upState = () => {
    setState(state + 1);
    console.log(state);
  };

  return (
    <div className="App">
      <button onClick={upState}>상태값 UP</button>
      <p>상태값은 {state}</p>
    </div>
  );
}

export default App;

버튼을 누르면 변경한 상태값이 정확히 랜더링 된다.

하지만 이상하게도 console.log(state)값은 이전 상태값을 출력한다.

이러한 문제 때문에 setState 이후 바로 상태값을 참조하여 다른 작업을 할 때 문제가 생기게 된다.

그리고 그 문제를 해결하기 위해서 react-thunk, react-saga등을 사용해 동기화 처리를 해준다.

그렇다면 왜 React는 상태값을 비동기적으로 처리하게 만들었을까?


3. React batch update

리액트는 batch update를 16ms 단위로 진행한다.

16ms 동안 변경된 상태 값들을 모아서 단 한번 리랜더링을 진행한다.

이러한 행동은 웹 페이지 랜더링 횟수를 줄여 좀 더 빠른 속도로 동작하게끔 만든다.

아래의 코드로 랜더링 횟수를 확인해 볼 수 있다.

import React, { useEffect, useState } from "react";

function App() {
  const [state1, setState1] = useState(1);
  const [state2, setState2] = useState(1);
  const [state3, setState3] = useState(1);
  const [renderCount, setRenderCount] = useState(0);

  const upState = () => {
    setState1(state1 + 1);
    setState2(state2 + 1);
    setState3(state3 + 1);
  };

  useEffect(() => {
    setRenderCount(renderCount + 1);
  }, [state1, state2, state3]);

  return (
    <div className="App">
      <button onClick={upState}>상태값 UP</button>
      <p>상태값1 {state1}</p>
      <p>상태값2 {state3}</p>
      <p>상태값3 {state3}</p>
      <p>랜더링 횟수 {renderCount}</p>
    </div>
  );
}

export default App;

코드를 실행하여 상태값 UP 버튼을 누르면 각각의 상태들을 1씩 올린다.

상태값을 바꿀 때 마다 리랜더링을 한다면 랜더링 횟수는 늘어나야 하는데 버튼 한 번당 동일하게 1씩 올라간다.

따라서 React는 일정 시간동안 변화한 상태값들을 모아 한 번에 처리하는 것을 알 수 있다.


결론

React의 setState 등이 비동기적으로 작동하는 이유는 일정시간동안 변화하는 상태를 모아 한 번에 랜더링 하기 위해서이다.


참고자료: https://medium.com/swlh/react-state-batch-update-b1b61bd28cd2

profile
FrontEnd Developer

0개의 댓글