본문 바로가기

프론트엔드/React

[React] useState 정리

728x90

useState란?

React에서 상태(state)를 관리하기 위한 함수

화면(UI)에 영향을 주는 데이터를 저장하고 그 값이 바뀌면 컴포넌트를 자동으로 렌더링시켜주는 역할입니다.

 

 

내부 동작 순서

1. 컴포넌트 최초 렌더링

  • React는 useState을 보고 이 컴포넌트에 하나의 상태로 기억합니다.
  • 이 상태는 React 내부 메모리(컴포넌트 인스턴스)에 저장됩니다.
  • 초기값은 딱 한번만 사용됩니다.

2. 렌더링 결과가 화면에 출력

3. 상태 변경 함수 호출

  • React가 이 컴포넌트의 상태가 바뀌었다는 것을 감지합니다.(상태 변경 감지)
  • 새로운 값을 React 내부 메모리에 기록합니다.
  • 이 컴포넌트만 다시 렌더링합니다.

4. 렌더링 재실행

  • 컴포넌트 함수가 다시 호출되지만 React는 기존 상태값을 유지한 채 새로운 UI를 계산합니다.
  • JSX를 새로 만들어서 Virtual DOM과 비교(diffing)후 변경된 부분만 실제 DOM에 반영합니다.

 

 

상태 업데이트 특징

1. 비동기

React는 성능을 위해 여러 상태 업데이트를 한 번에 모아서 처리합니다.

즉, 상태 업데이트를 호출해도 바로 상태가 변경되는 것이 아니라 다음 렌더링 때 반영하겠다고 예약을 합니다.

const [count, setCount] = useState(0);

setCount(count + 1);
setCount(count + 1); // 2가 아닐 수 있음

 

추천 방법

함수형 업데이트
setCount(prev => prev + 1)

이전 상태값에 의존하는 업데이트는 함수형 업데이트를 사용해야 여러 setState 호출 시 안전합니다.

  

2. 변경 감지

React는 상태가 바뀌었는지를 값이 아닌 참조 주소(reference)로 판단합니다.

const [count, setCount] = useState(0);

원시값(숫자, 문자열, boolean)은 값 자체로 비교가 가능하지만

배열, 객체, 함수 같은 참조형(reference type) 은 주소로 비교합니다.

const [arr, setArr] = useState([]);

arr.push(1);   // 잘못된 예시!
console.log(arr); // [1]

// 하지만 화면은 안 바뀜!

React 입장에서는 “같은 객체인데 뭐가 바뀌었지?” → 변경 감지 안 됨 → 리렌더 안 함

 

해결 방법

setArr([...arr, 1]); // 새로운 배열 생성

React가 변경을 감지하려면 새로운 객체 주소를 줘야 합니다.

같은 주소(reference)의 객체를 setState해도 리렌더링되지 않으므로, 화면 업데이트를 원하면 반드시 새로운 객체를 전달해야합니다.

 

 

정리

useState는 상태를 React 내부 메모리에 저장하고, 값이 바뀌면 해당 컴포넌트를 다시 렌더링합니다.
배열이나 객체 상태는 직접 수정하지 말고 항상 새로운 객체를 만들어 전달해야 변경을 감지합니다.