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를 재렌더링합니다.