⚙️ 우리 팀의 GitHub PR & 배포 자동화 세팅기
React 상태 관리 라이브러리 비교 정리Redux, Zustand, Recoil, Jotai, React Context, MobX
Redux : 명시적인 흐름과 불변성을 기반으로 한 가장 오래된 전통 강자• 특징- 액션 → 리듀서 → 스토어 구조의 Flux 패턴 기반- 모든 상태 변경을 명시적으로 추적 가능- Redux Toolkit을 함께 사용하면 boilerplate 감소• 장점- 디버깅 툴이 강력함 (Redux DevTools)- 상태 변경 흐름이 예측 가능하고 테스트 용이• 단점- boilerplate 코드가 많음 (RTK로 완화)- 러닝커브가 있음• 사용하기 좋은 순간- 상태 흐름이 명확해야 하거나 팀 규모가 클 때- 상태 변경 로직에 대한 추적과 테스트가 중요할 때
// Redux Toolkit 예시
const counterSlice = createSlice({
name: "counter",
initialState: 0,
reducers: {
increment: (state) => state + 1,
},
});
Zustand : 작고 빠르며 직관적인 훅 기반 상태 관리 라이브러리• 특징- Redux의 구조적 복잡성을 제거- 상태 선언과 액션을 함께 정의- useStore 훅을 통한 간결한 사용• 장점- 매우 가벼움, 러닝커브 낮음- React 외부에서도 상태 사용 가능 (vanilla JS)• 단점- 공식 DevTool이 제한적- 커스텀 로직이 많아지면 구조가 무너질 수 있음• 사용하기 좋은 순간- 빠른 프로토타이핑, 상태가 간단할 때- 기존 상태 관리보다 부담 없는 도입이 필요할 때
const useStore = create((set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
}));
Recoil : React 팀이 만든 공식 지향의 상태 관리. 아토믹한 상태 구성• 특징- atom 단위로 상태를 분리- selector로 파생 상태 구성 가능- 비동기와 동기 상태를 통합 관리• 장점- React 마인드셋과 매우 잘 맞음- 의존성 기반 자동 업데이트 (selector)• 단점- 상태의 분산 관리가 어려울 수 있음- 개발자 툴이 미성숙한 편• 사용하기 좋은 순간- 폼, 검색 필터, 데이터 파생 구조가 많은 앱- Recoil 기반 hook 분리 설계를 좋아할 때
const counterAtom = atom({ key: "counter", default: 0 });
const doubled = selector({
key: "doubled",
get: ({ get }) => get(counterAtom) * 2,
});
Jotai : 원자 단위 상태 관리의 미니멀리스트. Recoil의 대안• 특징- 기본적으로 useAtom() 하나로 작동- Recoil보다 더 단순하고 가볍게 설계됨- 비동기 atom도 선언만으로 사용 가능• 장점- 매우 간단한 사용법- 중첩된 atom 구조 없이 전역 상태를 구성 가능• 단점- 복잡한 상태 로직은 구조가 다소 난해할 수 있음• 사용하기 좋은 순간- 복잡도 낮은 프로젝트에서 최소한의 상태 관리가 필요할 때
const countAtom = atom(0);
const doubledAtom = atom((get) => get(countAtom) * 2);
React Context (useContext + useReducer) : React 기본 내장 기능으로 전역 상태 구현• 특징- 외부 라이브러리 없이 전역 상태 구성 가능- 상태 관리와 UI 간 분리가 어려움• 장점- 초소규모 앱에는 가장 적합- 의존성 없이 간단히 전역 상태 공유 가능• 단점- 상태가 커지면 리렌더 성능 이슈- 스케일업에 한계 있음• 사용하기 좋은 순간- 테마 설정, 로그인 정보, 언어 등 단순 공유 상태- 별도 라이브러리 도입 없이 빠르게 구성할 때
const CountContext = createContext();
const CountProvider = ({ children }) => {
const [count, setCount] = useState(0);
return (
<CountContext.Provider value={{ count, setCount }}>
{children}
</CountContext.Provider>
);
};
MobX : 반응형 상태 시스템. 관찰자 패턴 기반의 상태 추적• 특징- Observable을 통해 변경 감지- 매우 직관적이며 OOP 친화적• 장점- 코드 양이 적고 선언적- 자동 의존성 추적• 단점- 코드 흐름이 추적되기 어려울 수 있음- TypeScript 친화도는 일부 제한적• 사용하기 좋은 순간- 실시간 반응형 데이터 UI가 많은 앱- MVC 기반 아키텍처가 익숙한 팀
// Redux Toolkit 예시
const counterSlice = createSlice({
name: "counter",
initialState: 0,
reducers: {
increment: (state) => state + 1,
},
});
한 눈에 비교하기
* 현재 참여하는 프로젝트는 Recoil, Query-Parameter로 상태 관리항목 | Redux | Zustand | Recoil | Jotai | Context API | MobX |
---|---|---|---|---|---|---|
러닝커브 | 중~높음 | 매우 낮음 | 중간 | 매우 낮음 | 매우 낮음 | 낮음 |
코드 구조화 | 명확함 | 자유로움 | 아토믹 | 아토믹 | 자유로움 | 유연함 |
DevTool 지원 | 매우 강력 | 약함 | 미약 | 미약 | 없음 | 기본 있음 |
비동기 처리 | middleware 필요 | 자유로움 | 내장 지원 | 내장 지원 | 수동 구현 필요 | 자유로움 |
대표 사용 사례 | 팀 단위, 대규모 | 소규모, 개인 | 대중적 React 앱 | 빠른 앱 프로토타입 | 간단한 전역 공유 | 관찰 기반 UI |
참조 사이트https://redux.js.org/https://ssdragon.tistory.com/103https://zustand-demo.pmnd.rs/https://hyunki99.tistory.com/111https://recoiljs.org/ko/https://velog.io/@zooyaho/Recoil%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC-%ED%95%98%EA%B8%B0https://medium.com/@clockclcok/recoil-%EC%9D%B4%EC%A0%9C%EB%8A%94-%EB%96%A0%EB%82%98-%EB%B3%B4%EB%82%BC-%EC%8B%9C%EA%B0%84%EC%9D%B4%EB%8B%A4-ff2c8674cdd5https://jotai.org/https://velog.io/@ggong/%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC%EB%A5%BC-%EC%9C%84%ED%95%9C-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-jotaihttps://liebe97.tistory.com/49https://ko.legacy.reactjs.org/docs/context.htmlhttps://www.heropy.dev/p/EdhHX2https://velog.io/@jiyaho/React-Context-API%EC%9D%98-%EA%B0%9C%EB%85%90-%EB%B0%8F-%EC%82%AC%EC%9A%A9%EB%B2%95https://mobx.js.org/README.htmlhttps://techblog.woowahan.com/2599/https://blog.userinsight.co.kr/75https://joong-sunny.github.io/react/react6/