리액트 상태관리에 대하여

November 4, 2025

3 min read

현재 진행 중인 프로젝트에서 리덕스를 무분별하게 사용하다 보니, 컴포넌트 간 상태 관리가 전혀 통제되지 않고 있다는 생각이 들었다.

이번 기회에 상태 관리의 개념을 다시 정리하고, 현재 프로젝트의 상태 관리 구조가 올바르게 설계되어 있는지 점검할 필요가 있다고 느꼈다.

redux
뒤죽박죽 리덕스..

상태(State)란?

리액트에서 상태(state) 는 “시간에 따라 변하는 데이터”를 의미한다. 예를 들어 버튼 클릭 횟수, 로그인 여부, API에서 받아온 유저 정보 등이 모두 상태이다.

상태관리는 곧, 이 데이터를 어디에 저장하고 어떻게 업데이트하며 어느 범위까지 공유할지를 설계하는 일이다.

상태관리 종류

클라이언트 상태

브라우저 안에서 UI 동작과 직접적으로 연결된 상태

  • 모달 열림 여부
  • 현재 선택된 탭
  • 입력 폼의 값

서버 상태

서버(API)로부터 가져온 외부 데이터

  • 로그인한 사용자 정보
  • 게시글 목록
  • 알림, 통계 데이터 등

상태관리 도구

클라이언트 상태관리 도구

1. useState, useReducer (기본 Hook)

  • 리액트 기본 훅으로, 소규모 상태 관리에 적합

    const [count, setCount] = useState(0);
    
    return (
      <button onClick={()=> setCount(count + 1)}>클릭 횟수: {count}</button>
    );

2. Context API

여러 컴포넌트 간에 상태를 전역적으로 공유 가능

다만, 리렌더링 전파 문제로 대규모 상태에는 비효율적

const ThemeContext = createContext("light");
const App = () => (
  <ThemeContext.Provider value="dark">
    <Toolbar />
  </ThemeContext.Provider>
);

3. Redux / Redux Toolkit

  • 대규모 앱에서 가장 널리 쓰이는 전역 상태 관리 도구

  • 미들웨어, DevTools 등 생태계가 풍부

  • Redux Toolkit을 사용하면 코드가 훨씬 간결해짐

4. Recoil / Zustand / Jotai

  • 모던하고 가벼운 상태관리 라이브러리

  • 불필요한 리렌더링 최소화

  • 러닝커브가 낮아 빠르게 도입 가능

내가 사용해본건 useState, Context API, Redux 이다.

useState는 간편하지만, 컴포넌트 간 상태를 넘기다 보면 무한한 props 전달(Props Drilling) 이 발생하는 경우가 있었다.

Context API는 전역 상태를 공유하기에 편리하지만, 리렌더링이 자주 발생해 성능이 떨어질 때가 있었다.

Redux는 한 번 환경을 설정해두면 관리가 편하지만, 보일러플레이트 코드가 많고 코드가 깔끔하지 않은 단점이 있었다.


서버 상태관리 도구

1. React Query (TanStack Query)

  • API 요청, 캐싱, 에러 처리, 리페치를 자동으로 관리

  • 비동기 데이터 관리의 표준 도구

2. SWR

  • 간단한 서버 데이터 처리에 적합

  • 자동 캐시/리페치 지원 (Vercel 제작)

3. Apollo Client

  • GraphQL 전용 상태관리

  • 복잡한 GraphQL 데이터를 클라이언트에서 효율적으로 관리

아직 서버 상태 관리 도구는 사용해본 적이 없다. 앞으로 React Query를 도입해 리팩터링을 진행해보면 어떨까 생각 중이다.


정리

요즘 프로젝트를 하다 보니, Redux로 관리하는 상태가 10개가 훌쩍 넘어가버렸다. 점점 전역 상태가 많아지니까 “이게 진짜 필요한 상태인가?” 싶은 것들도 많아지고, 관리 자체가 점점 복잡해지고 있다는 걸 느꼈다.

그래서 이번 기회에 상태 관리 구조를 리팩터링해보기로 했다 (일단 계획은).

리팩터링 방향

  1. 서버 데이터 → React Query로 옮기기 (API 캐싱, 로딩, 에러 관리 자동화)

  2. 선택값 / 필터 / 폼 상태 → useReducer + Context로 분리 (기능 단위로 관리)

  3. Redux에는 인증, 전역 권한, 유저 정보만 남기기

조금 더 구조를 분석해봐야겠지만, 지금까지는 이 방향이 제일 괜찮아 보인다. 다음엔 React Query에 대해서 좀 더 깊게 공부해봐야겠다