React의 상태관리와 useState

가응·2025년 2월 14일
1
post-thumbnail

⭐state ( 상태 ) 란 ?

: 기억하고 관리해야하는 동적인 데이터 🐱

➡️버튼 클릭 횟수, 사용자가 입력한 텍스트, 서버에서 가져온 데이터 등은 모두 상태이다 !


😮상태에 영향을 주는 것
: 사용자 입력이나 서버의 응답, UI의 변화 등 ..

추가로 ...
리액트는 불변성을 기반으로 동작하기에,
기존 객체 수정 ( X )
새로운 객체를 생성해 교체👍 ( O )
-> 이렇게 참조 주소를 비교하는 것은 렌더링 성능에 도움을 준다

((변경된 부분만 업데이트 → 브라우저에 최소한의 성능 비용으로 변경 반영!해주기 때문 ))



⭐ 상태 관리의 필요성

React는 UI = f(상태)라는 개념을 기반으로 동작해서
즉, 상태가 변경되면 UI가 다시 렌더링된다.


올바르게 관리하지 않으면 어떤 문제가 발생할 수 있냐면 ..

  1. 비일관성: UI와 내부 데이터가 일치하지 않는 😮 상황 발생

  2. 복잡성 증가: 상태를 효율적으로 관리하지 않으면 코드가 복잡해짐 😢

  3. 디버깅 어려움: 상태 변경 흐름을 이해하기 어려워짐

.
.

나의 경우에는 비일관성 문제를 겪어서 렌더링이 바로 되지 않는 문제가 생겼었다


하지만 !!!

상태관리를 알아둔다면

이런 문제를 만들지 않을 수 있다 .. 👍🐱

상태 관리를 신경쓰기만 해도 UI와 데이터의 일관성을 유지하고,
코드의 가독성과 유지보수성 향상시킬 수 있으며,
디버깅이나 확장도 쉬워질 것이다~

그러니까 알아둬야한다..


우선 개념을 알아보도록 하자

⭐ React에서의 상태 관리 - useState

useState란?

useState는 React에서 컴포넌트의 상태를 선언하고 관리할 수 있도록 도와주는 훅이다.

📌 기본 개념

  1. 상태 변수 선언
  2. 상태 변경 함수 제공

앞서 말했듯이 리액트에서는
상태 변경 -> UI 리렌더링이 되기에
쉽게 ~! 동적 UI 를 구현할 수 있다

📌 기본 사용법

const [state, setState] = useState(initialValue);

  • state : 현재 상태 값
  • setState : 상태를 변경하는 함수
  • initialValue : 상태의 초기값 (숫자, 문자열, 배열, 객체 등이 가능함!)

코드를 살펴보며 설명해보면

import React, { useState } from 'react';

function Counter() {
  //⭐ 상태 변수 count, 상태 변경 함수 setCount
  const [count, setCount] = useState(0); 
//⭐➡️ count 초기값 : 0 -> 처음 렌더링때만 적용 !!

  //⭐버튼 클릭 시 상태 변경 ➡️ 클릭시 1 증가
  const handleIncrement = () => {
    setCount(count + 1); //⭐ 상태 변경 예약 & 렌더링 요청, 상태 변경시 리렌더링 ‼️
  };

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

export default Counter;

여기서 중요한 건
리액트는 이전 상태와 새로운 상태의 참조를 비교해서 렌더링 여부를 결정한다는 것이다.
.
.
그렇기에
setCount만 설정하면
상태 변경이 예약된 상태이고
위의 코드의 경우 onClick으로 상태가 변경되어야‼️
리렌더링이 이루어진다 🙆‍♀️


개념을 알았다면
좀 더 본격적으로 ☺️
본격적인 특징과 동작 원리를 공부해보자 ⭐


useState의 특징과 동작 원리

_

1. 비동기적 상태 업데이트

바로 직전에 설명했던 것이다 !~))

React는 성능 최적화를 위해 상태 업데이트를 비동기적으로 처리한다.

setState를 호출한 직후에는 변경된 값이 바로 반영되지 않고 ❌

Batch Processing(일괄 처리)를 통해 여러 상태 변경을 묶어서 처리한다.


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

const handleClick = () => {
  setCount(count + 1);
  console.log(count); // 예상: 1 / 실제: 0 (이전 값 출력)
};

이 코드의 문제는 무엇일까 ~?

.
.

정답 : 상태 업데이트를 예약만 하고 바로 실행하지 않기에 문제가 생긴다!
렌더링 시점의 count를 참조하기 때문에 항상 이전 값이 사용되고 있다 😮


어떻게 수정해주면 좋을까 ?
.
.

const handleClick = () => {
  setCount(prevCount => prevCount + 1);
  console.log(count); // 예상: 1 / 실제: 여전히 이전 값이지만 내부 로직은 올바르게 동작
};

➡️ 이렇게 함수형 업데이트를 활용해서 수정해줄 수 있다 ! 🐱

= 이러면 prevCount를 통해 최신 상태가 유지되고,
다음 렌더링 시에는 올바른 값이 화면에 표시된다. ☺️


2. 객체 상태 관리와 불변성

React는 불변성 원칙을 따르기 때문에 기존 객체를 직접 수정하면 안된다

➡️
기존 객체를 수정하면
참조 주소가 동일해서 변경이 없다고 판단하여
렌더링이 일어나지 않는다
.
.

  • 기존 객체 수정 → 리렌더링 ❌
const [user, setUser] = useState({ name: 'Lee', age: 24 });

const changeName = () => {
  user.name = 'Kim';
  setUser(user); // 참조 주소 동일 → 리렌더링 안 됨
};
  • 새로운 객체 → 리렌더링 😉
const changeName = () => {
  setUser(prevUser => ({ ...prevUser, name: 'Kim' }));
};

3. 독립적 상태 관리 💖

React에서는 각 상태가 독립적으로 관리된다.

🐱 관련된 상태는 객체 형태로 묶어서 관리 가능하다 → 코드 가독성 올라감 😮

const [user, setUser] = useState({ name: '', age: 0 });

const updateName = (newName) => {
  setUser(prevUser => ({ ...prevUser, name: newName }));
};

정리해보면 ~

  • 상태(state)는 React에서 동적 데이터를 관리하고
    변경 시 UI가 자동으로 리렌더링 🔃

  • 불변성 유지 중요 ⭐
    객체 수정 시 반드시 새로운 객체를 생성해야 리렌더링 작동

  • setState는 비동기적 ☺️‼️
    최신 상태를 보장을 위해서 함수형 업데이트를 사용해야 함

.
.
.
끝 ✌️

1개의 댓글

comment-user-thumbnail
2025년 2월 15일

오호~~ 공부를 어떻게 해야하는지 점점 감을 잡아가고있네요 기본원리부터 실제로 느꼈던 오류에서 활용된 개념과 느낀 점까지 너무 잘 적었어요 잘하고있습니다 최고!!

답글 달기