Front-End/React

[React] useState

시니철 2024. 10. 1. 12:03

State

React에서 state는 컴포넌트의 동적인 데이터를 관리하는 방법입니다. state는 각 컴포넌트가 자신의 데이터를 저장하고 이를 기반으로 UI를 업데이트할 수 있도록 해줍니다.

 

주요 특징

  • 로컬 상태 관리 : 각 컴포넌트는 자체 state를 가질 수 있으며, 이 상태는 해당 컴포넌트 내에서만 사용됩니다. 즉, 다른 컴포넌트와 공유되지 않습니다.
  • 비동기적 업데이트 : 상태 업데이트는 비동기적으로 이루어질 수 있습니다. 여러 개의 setState 호출이 있을 경우, React는 최적화하여 배치 처리할 수 있습니다.
  • 초기 상태 설정 : 컴포넌트가 처음 렌더링될 때 초기 state를 설정할 수 있으며, 클래스 컴포넌트에서는 생성자(consteuctor)에서, 함수형 컴포넌트에서는 useState 훅을 사용하여 설정합니다.
  • UI와 연동 : state가 변경되면 React는 자동으로 해당 컴포넌트를 리렌더링하여 UI를 업데이트 합니다. 이를 통해 사용자는 최신 상태를 항상 볼 수 있습니다.
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // 초기 state 설정

  const increment = () => {
    setCount(count + 1); // state 업데이트
  };

  return (
    <div>
      <p>현재 카운트: {count}</p>
      <button onClick={increment}>증가</button>
    </div>
  );
}

 

위 코드에서 count는 상태 변수이고, setCount는 상태를 업데이트하는 함수입니다. 버튼을 클릭할 때마다 count가 증가하고 UI가 업데이트됩니다.


참조형 State

  const [gameHistory, setGameHistory] = useState([]);

  const handleRollClick = () => {
    const nextNum = random(6);
    gameHistory.push(nextNum);
    setGameHistory(gameHistory); // state가 제대로 변경되지 않음
  };

 

위 코드에서 gameHistory는 배열의 값으로 가지고 있습니다. 하지만 push 메소드를 사용해 배열의 값을 변경한 후, 변경된 배열을 setGameHistory로 설정하면 코드가 제대로 동작하지 않습니다.

 

이유는 gameHistory 상태가 배열 값 자체를 가지고 있는 것이 아니라 그 배열의 주솟값을 참조하고 있기 때문입니다. push 메소드를 통해 배열 안의 요소를 변경해도, React 입장에서는 여전히 gameHistory가 참조하는 주솟값은 동일하다고 판단합니다. 따라서 상태가 바뀌었다고 인식하지 않게 됩니다.

 

그래서 참조형 상태를 활용할 때는 반드시 새로운 참조형 값을 만들어 상태를 변경해야 합니다.

  const [gameHistory, setGameHistory] = useState([]);

  const handleRollClick = () => {
    const nextNum = random(6);
    setGameHistory([...gameHistory, nextNum]); // state가 제대로 변경
  };

 

위와 같이 setGameHistory([...gameHistory,nextNum]);를 사용하면, 기존의 gameHistory 배열을 복사하여 새로운 배열을 생성합니다. 이렇게 하면 gameHistory의 참조가 변경되므로, React는 상태가 변경되었다고 인식하고 UI를 재렌더링합니다.