useState의 비동기적 처리와 동기적 처리 방법

posinity·2022년 12월 8일
0

React

목록 보기
4/58

useState의 업데이트 방식은 크게 두가지가 있습니다.
함수형 업데이트일반 업데이트입니다.

일반 사용법과 함수형 업데이트 방식의 차이점이 무엇일까요? 두개의 코드를 비교해봅시다.

useState의 비동기적 처리

먼저 일반 업데이트 방식으로 onClick안에서 setNumber(number + 1) 를 3번 호출했습니다. number가 1씩 증가하는군요.

// src/App.js

import { useState } from "react";

const App = () => {
  const [number, setNumber] = useState(0);
  return (
    <div>
			{/* 버튼을 누르면 1씩 플러스된다. */}
      <div>{number}</div> 
      <button
        onClick={() => {
          setNumber(number + 1); // 첫번째 줄 
          setNumber(number + 1); // 두번쨰 줄
          setNumber(number + 1); // 세번째 줄
        }}
      >
        버튼
      </button>
    </div>
  );
}

export default App;

이렇게 동작하는 이유는 useState는 비동기적 처리를 하기 때문입니다.

비동기적 처리란, 어떤 작업을 처리하면서 다른 작업도 진행하는 것을 뜻합니다.

예를 들어, 카페에 갔는데 사장님 혼자 주문받고 일하면, 손님 한 명의 주문을 받고 음료를 제조하는 동안 다른 손님은 주문도 불가능하죠. 이것이 동기 처리입니다. 하지만 직원을 두어 주문 담당과 제조담당을 따로 둔다면 손님은 주문을 계속해서 할 수 있고, 그동안 제조담당은 음료를 계속해서 제조할 수 있습니다. 이것이 비동기 처리입니다.

setState는 리렌더링 될 때까지 값을 갱신하지 않습니다. 리액트가 효율적으로 렌더링하기 위해 여러 개의 상태 값 변경 요청을 batch(일괄 처리) 처리하기 때문입니다.

그렇기 때문에 number가 0인 상태에서 +1만 계속 해주고 있는 셈이죠.
batch 처리의 이유는 성능 이슈 때문입니다. 리렌더링을 발생하는 setState가 일어날 때마다 리렌더링이 일어난다면 엄청나게 많은 렌더링이 일어나겠죠.

incrementCount() {
  // 주의: 이 코드는 예상대로 동작하지 *않을 것*입니다.
  this.setState({count: this.state.count + 1});
}

handleSomething() {
  // `this.state.count`가 0에서 시작한다고 해봅시다.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
  // React가 컴포넌트를 리렌더링할 때 `this.state.count`는 3이 될 것 같은 예상과 달리 1이 됩니다.

  // 이것은 `incrementCount()` 함수가 `this.state.count`에서 값을 읽어 오는데
  // React는 컴포넌트가 리렌더링될 때까지 `this.state.count`를 갱신하지 않기 때문입니다.
  // 그러므로 `incrementCount()`는 매번 `this.state.count`의 값을 0으로 읽은 뒤에 이 값을 1로 설정합니다.

}

동기적 처리 방법

이번에는 함수형 업데이트 방식으로 동일하게 작동시켜보겠습니다. number가 3씩 증가하네요.

// src/App.js

import { useState } from "react";

const App = () => {
  const [number, setNumber] = useState(0);
  return (
    <div>
			{/* 버튼을 누르면 3씩 플러스 된다. */}
      <div>{number}</div>
      <button
        onClick={() => {
          setNumber((previousState) => previousState + 1);
          setNumber((previousState) => previousState + 1);
          setNumber((previousState) => previousState + 1);
        }}
      >
        버튼
      </button>
    </div>
  );
}

export default App;

함수를 전달하게 되면 함수 안에서 이전 state값에 접근할 수 있고, 순차적으로 처리하기 때문에 동기적 처리가 됩니다.

참고자료

[React] useState의 비동기적 동작
컴포넌트 State
[ React ] useState 의 렌더링과 함수형 업데이트

profile
문제를 해결하고 가치를 제공합니다

0개의 댓글