리액트 상태 관리 총정리: Context API부터 Zustand까지
만약 여러분이 50층짜리 초고층 펜트하우스에 살고 있다고 상상해 보겠습니다. 1층 로비 경비실에 전달해야 할 중요한 서류가 생겼는데, 아파트에 엘리베이터나 인터폰이 없다면 어떻게 해야 할까요?
아마도 49층 이웃의 문을 두드려 서류를 넘기고, 그 이웃은 다시 48층으로, 48층은 47층으로… 이렇게 무려 50번의 릴레이를 거쳐야만 겨우 1층에 도달할 수 있을 것입니다. 듣기만 해도 숨이 턱 막히고 비효율적이죠? 놀랍게도 리액트(React)로 웹을 개발할 때 초보자들이 가장 흔하게 겪는 문제가 바로 이와 똑같습니다.
지난 11편에서는 하나의 방(컴포넌트) 안에서 온도나 조명을 조절하는 useState와 useEffect 훅(Hooks)에 대해 알아보았습니다. 하지만 방을 넘어 아파트 단지 전체가 공유해야 하는 데이터가 생기면 어떻게 될까요? 오늘은 복잡하게 얽힌 리액트의 데이터 흐름을 한 방에 정리해 줄 '전역 상태 관리(Global State Management)'의 세계로 여러분을 안내하겠습니다.
프롭 드릴링(Prop Drilling): 50층 계단을 오르내리는 심부름
리액트의 데이터는 기본적으로 위에서 아래로, 즉 부모 컴포넌트에서 자식 컴포넌트로만 흐릅니다. 이를 '단방향 데이터 바인딩'이라고 부르죠. 최상위 컴포넌트(펜트하우스)에 있는 데이터를 까마득히 아래에 있는 하위 컴포넌트(1층 경비실)에서 사용하려면, 중간에 있는 모든 컴포넌트(2~49층)를 거쳐서 데이터를 전달해야만 합니다.
"이 데이터는 제게 필요 없지만, 제 밑에 있는 자식에게 전달해야 하니 일단 받겠습니다."
이처럼 중간 단계의 컴포넌트들이 자신에게 필요 없는 데이터(Props)를 오직 아래로 전달하기 위해 떠안게 되는 현상을 프롭 드릴링(Prop Drilling)이라고 합니다. 마치 드릴로 땅을 파고 내려가듯 데이터를 계속 아래로 뚫고 내려간다는 뜻이죠. 프로젝트 규모가 작을 때는 문제가 없지만, 대단지 아파트처럼 컴포넌트가 수십, 수백 개로 늘어나면 코드는 스파게티처럼 꼬이고 유지보수는 악몽이 됩니다. 이 문제를 해결하기 위해 등장한 것이 바로 '전역 상태 관리' 도구들입니다.
아파트 단지 내 사내방송, Context API (소규모 단지용)
프롭 드릴링을 피하는 가장 기본적인 방법은 리액트가 자체적으로 제공하는 Context API를 사용하는 것입니다. 부동산에 비유하자면 '아파트 단지 내 사내방송 시스템'이라고 할 수 있습니다.
관리사무소(Provider)에서 마이크를 잡고 방송을 하면, 굳이 층마다 문을 두드리지 않아도 스피커(Consumer)가 있는 세대라면 어디서든 다이렉트로 방송 내용을 들을 수 있죠. 외부 라이브러리를 설치할 필요 없이 리액트 내장 기능만으로 구현할 수 있어 세팅이 매우 간편합니다.
하지만 치명적인 단점이 하나 있습니다.
Context API는 데이터가 조금만 바뀌어도 방송망에 연결된 모든 컴포넌트를 다시 렌더링(새로고침)하는 경향이 있습니다. 예를 들어 "302호 주민분, 택배 찾아가세요"라는 개인적인 알림조차 아파트 전체 스피커로 울려 퍼지는 셈입니다. 불필요한 소음(렌더링)이 발생해 앱의 성능이 저하될 수 있죠.
- 언제 사용하면 좋을까요?
- 자주 변하지 않는 데이터에 적합합니다.
- 사용자의 로그인 여부, 다크 모드/라이트 모드 테마 설정, 다국어 지원 등 '단지 전체의 기본 환경 설정'을 관리할 때 찰떡궁합입니다.
체계적인 대단지 관리사무소, Redux (대단지용)
Context API의 성능 문제를 해결하고, 거대한 데이터를 체계적으로 관리하기 위해 등장한 프론트엔드 생태계의 절대 강자가 바로 Redux(리덕스)입니다. 리덕스는 수천 세대가 사는 '1군 브랜드 대단지 아파트의 관리사무소'와 같습니다.
리덕스는 데이터(상태)를 아무나 함부로 수정하지 못하도록 매우 엄격한 규칙을 적용합니다. 어떤 입주민이 헬스장 비밀번호를 바꾸고 싶다면 다음의 절차를 거쳐야 합니다.
- Action (요청서 작성): "헬스장 비밀번호를 1234로 변경해 주세요"라는 공식 요청서를 작성합니다.
- Dispatch (접수): 이 요청서를 관리사무소 창구에 접수합니다.
- Reducer (매뉴얼 처리): 관리사무소 직원은 정해진 매뉴얼(Reducer)에 따라 요청서에 문제가 없는지 확인하고, 승인 후 장부에 기록합니다.
- Store (중앙 금고): 변경된 최신 데이터는 아파트의 유일한 중앙 금고(Store)에 안전하게 보관되며, 필요한 사람에게만 통보됩니다.
이처럼 절차가 명확하기 때문에 데이터가 언제, 어떻게, 왜 변했는지 추적하기가 매우 쉽습니다. 에러가 발생해도 원인을 금방 찾을 수 있죠. 하지만 단점도 명확합니다. 작은 데이터를 하나 바꿀 때도 매번 요청서를 쓰고 매뉴얼을 만들어야 하니 작성해야 할 코드의 양(보일러플레이트)이 너무 많고 복잡하다는 것입니다. 10세대짜리 빌라에서 이런 시스템을 도입한다면 배보다 배꼽이 더 커지겠죠.
최신형 스마트홈 중앙제어 패널, Zustand (최신 트렌드)
최근 프론트엔드 개발자들 사이에서 리덕스의 무거운 절차에 지쳐 새롭게 떠오른 샛별이 있습니다. 바로 독일어로 '상태'를 뜻하는 Zustand(주스탠드)입니다. 주스탠드는 복잡한 서류 작업 없이, 거실 벽면에 붙어 있는 '최신형 스마트홈 월패드(Wall-pad)' 하나로 모든 것을 통제하는 방식입니다.
리덕스처럼 중앙 저장소(Store)를 가지면서도, 사용법은 리액트 훅(Hooks)과 거의 똑같아 직관적입니다. Action, Dispatch, Reducer 같은 복잡한 개념을 몰라도 당장 오늘부터 도입할 수 있을 만큼 쉽습니다.
| 비교 항목 | Redux (리덕스) | Zustand (주스탠드) |
|---|---|---|
| 비유 | 엄격한 대단지 관리사무소 | 심플한 스마트홈 월패드 |
| 초기 세팅 | 매우 복잡함 (Redux Toolkit 필수) | 매우 간단함 (코드 몇 줄이면 끝) |
| 코드량 | 많음 (보일러플레이트 높음) | 적음 (핵심 로직만 작성) |
| 성능 최적화 | 우수함 | 매우 우수함 (필요한 부분만 렌더링) |
| 학습 난이도 | 높음 (입문자에게 장벽) | 낮음 (초보자 친화적) |
내 프로젝트에 딱 맞는 상태 관리 도구 고르기 (체크리스트)
그렇다면 우리는 어떤 도구를 선택해야 할까요? 정답은 '프로젝트의 규모와 성격'에 달려 있습니다. 다음 체크리스트를 확인해 보세요.
- Context API를 선택하세요: 데이터 변경이 거의 없고, 테마나 다국어 설정 같은 단순한 전역 데이터만 필요할 때.
- Zustand를 선택하세요: 빠르고 가볍게 프로젝트를 시작하고 싶을 때. 최근 스타트업이나 신규 프로젝트에서 가장 선호하는 트렌디한 선택지입니다.
- Redux를 선택하세요: 금융권이나 대형 이커머스처럼 상태 변화가 매우 복잡하고, 엄격한 데이터 추적과 안정성이 최우선인 대규모 프로젝트일 때.
여기서 중요한 포인트는요, '무조건 전역 상태 관리가 정답은 아니다'라는 것입니다. 방 안에서만 쓰는 스탠드 조명(지역 상태, useState)을 굳이 아파트 중앙 통제실(전역 상태)에 연결할 필요는 없습니다. 데이터가 정말 여러 컴포넌트에서 공유되어야 하는지 먼저 고민하는 습관이 훌륭한 프론트엔드 개발자를 만듭니다.
지금까지 리액트의 복잡한 데이터 흐름을 깔끔하게 정리해 주는 상태 관리 도구들에 대해 알아보았습니다. 이제 우리는 어떤 복잡한 데이터가 와도 흔들리지 않는 튼튼한 아파트의 뼈대와 중앙 통제 시스템을 갖추게 되었습니다.
하지만 아무리 멋진 아파트라도 현관문과 복도, 엘리베이터가 없다면 방과 방 사이를 이동할 수 없겠죠? 다음 13편에서는 사용자가 클릭 한 번으로 페이지를 자유롭게 넘나들게 해주는 웹의 동선 설계, 'React Router(리액트 라우터)와 SPA 네비게이션'에 대해 본격적으로 파헤쳐 보겠습니다. 즐겨찾기 해두시고 다음 편도 기대해 주세요!