본문 바로가기

react

[React] 상태관리 라이브러리 비교하기(redux, zustand, jotai, recoil)

react 기반의 웹 프로젝트에서 상태 관리 라이브러리는 유지보수를 위해 필수적이다. 여러 개의 라이브러리 중에서 어떤 걸 사용해야 할까. 많은 글들이 redux, zustand, jotai, recoil, 그리고 추가로 valtio 등을 추천한다. 이 글에서는 앞의 4가지를 비교하면서 어떤 상황에 어떤 라이브러리가 적합한지 판단한다.

 

목표
4개의 라이브러리 간 특징을 비교하고 어떤 상황에서 사용하면 좋을지 판단하기

 

 

개발 철학


이들의 컨셉은 크게 FLUX와 Atom 두 가지로 나뉜다.

 

FLUX
FLUX는 중앙집중식 상태관리 시스템을 의미하는 것으로, 컴포넌트에서 사용되는 state와 state setter 로직을 단일한 store에서 관리한다는 방침이다. 이는 가장 말단에서 가장 작은 state가 필요한 컴포넌트 조차도 중앙의 거대한 state를 참조하고 결코 자기 마음대로 상태 변경을 할 수 없이 중앙에 요청을 보내야 한다.

Redux와 Zustand가 이 방식이다.

 

Atom

반면, Atom은 분산식 상태관리 시스템이다. 여기서 Atom은 react의 useState와 거의 유사한 state 기능을 가지고 있다. 단지, Atom은 전역에서 작동가능하다. 각 컴포넌트는 자신에게 필요한 atom을 만든다는 점에서 앱 전체의 관점에서 보면 state는 분산되어 있고, state의 변경 로직 역시 분산되어 있다.

Recoil과 Zutai가 이 방식이다.

 

코드 작성 스타일


FLUX

FLUX디자인은 Atom에 비해 상대적으로 많은 코드가 필요하다. Atom은 useState처럼 컴포넌트 단에서 필요 시 바로 state를 사용하고 update하는 것과 다르게, FLUX는 중앙의 거대한 state를 필요에 맞게 자르는 작업(useSelector)과 일정한 양식의 액션 객체를 반환하는 action creator 생성, 그리고 중앙의 reducer를 작성하는 작업 등이 필요하다. 

이에 대한 반박으로 앱이 크고 복잡하다면 관리 로직이 많아지는 것이 당연하다 할 수 있다. 하지만, 리덕스의 이런 작업은 switch문이나 단순 객체를 반환하는 함수 작성 등 상당히 단순한 작업의 반복이기도 하다.

참고: 리덕스 측의 대안
다만, 이런 단점은 리덕스 운영 측에서 인지하고 빠르게 대안을 마련하였다. redux-toolkit이라는 공식 라이브러리는 반복적으로 작성되는 코드를 크게 감소시킨다. 단, 기존의 직관적인 바닐라 자바스크립트 코드가 아니라, 프레임워크처럼 자체 규칙을 갖춘 형태라 러닝커브는 약간 높아진 느낌이다. 

 

redux와 zustand를 비교할 땐 zustand가 더 적은 코드를 필요로 한다.

 

Atom

Atom 방식은 코드가 많이 필요하지 않다. atom 생성을 위한 코드, atom 간 의존성을 처리하는 로직인 selector 정도만 있으면 된다. state를 업데이트하는 방식 역시도 FLUX의 action/dispatch와 다르게 상당히 자유롭다.

 

유지 보수


이 부분은 두 가지를 생각해볼 수 있는데, 얼마나 더 적은 코드를 사용하는가와 데이터 흐름 추적이 얼마나 용이한가로 구분된다.

 

FLUX

많은 코드를 사용하니 직관성은 떨어질 수 있지만, 커뮤니티 반응은 이 디자인이 유지 보수의 측면에서 Atom보다 낫다고 말한다. 그 이유는 수많은 컴포넌트에서의 상태와 업데이트 로직이 하나의 store에서 이뤄지다 보니, store에서 쉽게 데이터 흐름을 파악할 수 있어서다. 

게다가 Redux는 Redux-dev-tool이라는 크롬 확장 도구를 통해 강력한 디버깅을 지원한다. 이는 Zustand 역시 이 도구를 사용할 수 있다는 점에서 마찬가지다.

 

Atom

state와 state set 로직이 컴포넌트에 분산되어 있는 Atom은 앱의 규모가 커질수록 데이터 흐름을 추적하기 어려워진다. 작은 앱에서는 빠른 설정과 적은 코드의 이점이 있지만,규모가 크고 복잡한 앱에서는 유지보수 측면에서 FLUX보다 불리하다.

 

용량


이 부분은 어느 한 디자인이 용량을 많이 먹는게 아니라, 라이브러리 별로 보는 게 나을 것이다.

npm 기준으로 4 라이브러리의 unpacked size는 다음과 같다.

라이브러리 redux-toolkit zustand recoil zutai
용량 5.51mb 327kb 2.21mb 430kb

 

이런 양상이 나타나는 이유는 우선 redux와 recoil에 비해 신생 라이브러리인 zustand와 zutai는 가볍고 간단한 기능이라는 컨셉을 잡고 나왔다는 점에 있다. zustand는 redux의 스타일을, zutai는 recoil의 스타일에서 영감을 받았지만 이런 장점이 부각되며 차세대 라이브러리로 각광받고 있다.

 

문서화 및 커뮤니티


라이브러리는 실제 앱에 적용되는 과정에서 예상치 못한 오류들이 발생하기 때문에 참고할 수 있는 공식문서나 커뮤티니, 개인의 이슈 해결 과정 문서가 많이 필요하다. 이런 점에서 redux는 가장 오래된 라이브러리인 만큼 풍부한 레퍼런스를 가지고 있다.

이는 recoil 역시 마찬가지이며, 차세대 라이브러리인 zustand와 zutai는 상대적으로 빈약하다. 하지만, npm trend의 최근 지표를 보면 recoil은 하락세가 멈추지 않고 두 라이브러리는 상승세를 유지하고 있다.

이는 recoil의 업데이트가 너무 느려서 사용자들의 이슈 제기를 제대로 처리하지 못하고 있다는 점, 반면 두 라이브러리는 잘 해결하며 성장한고 있다는 점을 반영하는 것 같다.

이미 zutai의 다운로드 지표가 recoil을 앞지른 점도 보아, 문서화와 커뮤니티의 유지는 recoil이 가장 좋지 않아 보인다.

 

SSR 지원여부


기존에는 redux가 CSR과 SSR 양 쪽 모두에 특화된 라이브러리이고 나머지는 CSR에 특화된 라이브러리라는 인식이 강했다. 하지만, zustand나 zotai 역시 SSR을 위한 기능과 훅을 지원하기 시작하면서, 많은 레퍼런스와 오래된 안정성을 가진 redux, 가벼움과 간단한 기능을 가진 zustand, zotai로 판도가 만들어졌다. 

반면, recoil은 여전히 ssr에 대한 공식 지원을 하지 않고 있다.

 

 

배운 점 & 사용 방향


필자는 최근까지 redux와 recoil만을 사용했으나 이 둘을 선택할 때의 기준에 대해, 그리고 최근의 라이브러리 동향에 대해서도 잘 알지 못했다.

이 기회에 찾아본 결과, 상태 관리 라이브러리는 일단 개발자가 선호하는 관리 패턴과 앱의 규모 및 안정성에 따라 달라지고 어느 하나가 특출나게 낫다고 판단하긴 어려웠다.

보수적인 안정성을 추구하고 국내 시장을 고려한다면 redux가 낫고, 가볍고 간단한 앱을 개발할 때는 zustand나 jotai가 좋을 것이다. 또한, flux와 atom의 선호에 따라 zustand와 jotai를 선택할 수 있다.

recoil은 1~2년 전까지만 해도 분명히 좋은 라이브러리였지만 지금은 이슈에 대한 느린 처리와 중단에 가까운 업데이트 속도 때문에 하향세를 걷고 있고, 이게 변하지 않는다면 선택하기 어려울 것 같다. 차라리 jotai를 선택하는 것이 나아 보인다. 

 

 

참고자료

https://blog.logrocket.com/jotai-vs-recoil-what-are-the-differences/

 

https://medium.com/@kparth_/jotai-or-recoil-a-new-era-of-state-management-in-react-a-comparison-with-redux-zustand-200ae6b63f1e

 

 

https://blog.toktokhan.dev/react-%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC-%EC%B5%9C%EA%B0%95%EC%9E%90%EB%8A%94-f0753ad7d186