[React] state 함수형 업데이트

hoonsbory·2022년 12월 28일
0

React State의 함수형 업데이트

  • 리액트의 state는 성능을 위해 여러 state의 변경이 일어나면 batching하여 업데이트를 진행한다
  • batching은 전달된 오브젝트들을 하나로 합치는 작업이다. (object composition)
const singleObject = Object.assign({},
  objectFromSetState1,
  objectFromSetState2,
  objectFromSetState3
);

이렇게 리액트는 모든 state의 변경을 한데 모아 배칭하여 리렌더링한다.

이 방법은 여러 state의 변경을 한번에 모아 처리하므로 성능이 좋지만 아래와 같은 상황에서 원하는 결과를 얻기가 힘들다. (모든 변경마다 리렌더링을 하면 성능에 문제가 생김)

import React, { useState } from "react"

function App() {

  const [num, setNum] = useState(1)

  async function plus() {
    setNum(num + 1)
    setNum(num + 1)
    setNum(num + 1)
  }

  async function minus() {
    setNum(num - 1)
  }

  return (
    <div className="App">
      <h1>{num}</h1>
      <button onClick={plus}>PLUS</button>
      <button onClick={minus}>MINUS</button>
    </div>
  );
}

export default App;

그 이유는 위에서 설명한 object composition에 있다. 위 세가지 변경을 한데 모아 처리하므로 결과는 한번 실행한 것과 같다.

문제가 되는 코드의 동작은 위와 같다. 한번에 처리하여 모두 처리 전 num값을 가지고 있어 1 + 1 의 결과만이 들어간 것이다.

그렇다면 위와 같이 최신의 state값을 참조하여 
여러번의 변경을 수행해야하는 로직은 어떻게 작성해야할까?

바로 아래와 같이 함수형 업데이트를 사용하여 항상 최신값을 가져와 set을 해야한다.

import React, { useState } from "react"

function App() {

  const [num, setNum] = useState(1)

  async function plus() {
    setNum(num => num + 1)
    setNum(num => num + 1)
    setNum(num => num + 1)
  }

  async function minus() {
    setNum(num - 1)
  }

  return (
    <div className="App">
      <h1>{num}</h1>
      <button onClick={plus}>PLUS</button>
      <button onClick={minus}>MINUS</button>
    </div>
  );
}

export default App;

useState의 내부 로직은 아래와 같다

// React Hooks
    // ----------------------------------------------------------------------

    // based on the code in https://github.com/facebook/react/pull/13968

    // Unlike the class component setState, the updates are not allowed to be partial
    type SetStateAction<S> = S | ((prevState: S) => S);

0개의 댓글