본문 바로가기

리액트

⭐ 9편 — 리액트 상태 관리 기본기: Context API vs Redux 실전 비교, 초보자도 알 수 있게 정리

⭐ 9편 — 리액트 상태 관리 기본기: Context API vs Redux 실전 비교, 초보자도 알 수 있게 정리


리액트로 프로젝트를 만들다 보면
“어느 컴포넌트에서든 공통으로 필요한 데이터”가 반드시 생깁니다.
예를 들어:
로그인 정보
사용자 정보
장바구니
다크모드 설정
알림 상태
언어 설정(ko/en)
이런 값들은 한두 개 컴포넌트만 쓰는 게 아니라
여러 페이지 / 여러 컴포넌트에서 공통으로 필요합니다.
이럴 때 사용하는 것이 전역 상태 관리입니다.
리액트에서 전역 상태를 관리할 때 가장 많이 쓰는 방식은
✔ Context API
✔ Redux
이 두 가지입니다.
둘 다 장단점이 확실하고, 프로젝트의 성격에 따라 선택해야 합니다.
이번 글에서는 “언제 어떤 걸 써야 하는지”까지 명확하게 알려드릴게요.


✅ 1. Context API란?

Context API는 리액트 자체에 내장된 가벼운 전역 상태 관리 도구입니다.
외부 라이브러리 없이 바로 사용할 수 있습니다.
✔ 가장 큰 특징
전역으로 데이터를 저장해두고
하위 컴포넌트 어디서든 꺼내 쓸 수 있음
props drilling 문제 해결
✔ 기본 구조 예제
1) Context 생성
const UserContext = createContext(null);
2) Provider로 감싸 전역 값 전달
<UserContext.Provider value={user}>
<App />
</UserContext.Provider>
3) 필요한 컴포넌트에서 값 사용
const user = useContext(UserContext);
이렇게 하면 props로 값을 계속 내려줄 필요가 없습니다.

 

🔥 Context API의 장점

✔ 외부 라이브러리 필요 없음
✔ 코드가 간단함
✔ 소규모 프로젝트에서 효율적
✔ 중첩된 props 구조를 깔끔하게 정리 가능


🚨 Context API의 단점

❗ 1) 상태가 바뀌면 Provider 아래 모든 컴포넌트가 리렌더링됨
전역 상태를 너무 많이 넣으면 오히려 성능이 떨어질 수 있습니다.
❗ 2) 상태가 복잡해지면 관리하기 어려움
비동기 로직
복잡한 reducer
액션 관리
이런 게 필요해지면 한계가 드러납니다.
👉 이런 상황에서는 Redux와 같은 전문 상태관리 도구가 필요합니다.


✅ 2. Redux란 무엇인가?

Redux는 리액트 생태계에서 가장 널리 쓰이는
전문 전역 상태 관리 라이브러리입니다.
Context API보다 배우기는 조금 어렵지만,
대규모 프로젝트나 복잡한 상태가 필요한 상황에서는 사실상 표준입니다.


🔥 Redux의 핵심 철학(3가지)

단일 저장소(Store)
모든 전역 상태를 한 곳에서 관리
읽기 전용 상태
상태를 직접 바꾸지 않고 action을 통해 변경
변화는 순수 함수(reducer)로만 업데이트
예측 가능하고 테스트가 쉬워짐
✔ Redux가 강력한 이유
상태 흐름이 명확해서 디버깅 쉽다
Redux DevTools로 상태 변경을 추적할 수 있다
상태 업데이트가 복잡해도 체계적으로 관리된다
대규모 프로젝트에서 유지보수성이 탁월하다


🚀 Redux Toolkit이 표준이 된 이유

과거 Redux는
보일러플레이트 코드가 많고
문법이 복잡했지만,
최근에는 Redux Toolkit(RTK) 으로 모든 문제가 해결되었습니다.
RTK 기준으로 Redux를 배우면
사실 Context보다 간단하다고 느껴질 정도입니다.


⭐ Context API vs Redux 비교 정리


구분 Context API Redux
규모 소규모 중·대규모
난이도 쉬움 중간
사용 목적 단순 전역 값 공유 복잡한 상태 로직, 비동기 처리
성능 상태 변경 시 Provider 아래 전체 리렌더링 변경된 부분만 업데이트
디버깅 어려움 DevTools로 매우 쉬움
코드 구조 간단하지만 확장성 낮음 구조화가 잘됨


🔥 실제 프로젝트 기준 선택 가이드 (중요!)

✔ Context API를 쓰는 게 더 좋은 상황
로그인 정보 같이 단순한 전역 상태
다크모드 설정
프로젝트 규모가 작음
상태가 비동기적으로 복잡하게 변하지 않음
✔ Redux를 써야 하는 상황
상태가 여러 형태로 복잡하게 변함
API 호출/로딩/에러 관리
대규모 프로젝트
관리자 페이지처럼 데이터가 많음
디버깅이 중요함
실무에서는 대부분 로그인·테마는 Context,
데이터 흐름은 Redux로 나누는 방식을 많이 씁니다.


🔍 실전 예제: Context + Reducer 조합

Context가 복잡해지면 reducer와 함께 쓰는 경우가 많습니다.
const UserStateContext = createContext();
const UserDispatchContext = createContext();
function userReducer(state, action) {
switch (action.type) {
case "LOGIN":
return { ...state, user: action.payload };
default:
return state;
}
}
function UserProvider({ children }) {
const [state, dispatch] = useReducer(userReducer, { user: null });
return (
<UserStateContext.Provider value={state}>
<UserDispatchContext.Provider value={dispatch}>
{children}
</UserDispatchContext.Provider>
</UserStateContext.Provider>
);
}
Context만으로도 꽤 강력한 구조를 만들 수 있지만,
이런 형태가 많아지면 Redux를 쓰는 게 훨씬 효율적입니다.


✨ 마무리: 전역 상태 관리 선택은 “프로젝트 규모”가 정한다

Context API와 Redux는 경쟁 관계가 아니라
“상황에 따라 선택하는 두 가지 도구”입니다.
✔ 작은 프로젝트 → Context API
✔ 중·대규모 프로젝트 → Redux Toolkit
둘의 장단점을 알고 선택하면
리액트 프로젝트의 구조가 훨씬 안정적이고 유지보수가 쉬워집니다.