준영
세 가지 전역 상태 라이브러리의 유사점과 차이점
Zustand와 Redux의 차이점
디렉토리 구조
Redux는 features 디렉토리 구조를 제안하지만, Zustand는 구조에 대한 의견을 제시하지 않는다.
따라서 Redux는 어느 정도 정형화된 구조를 제안하기 때문에 대규모 어플리케이션에 유용하다.
반면, Zustand는 이러한 구조를 개발자가 직접 구성해야하기 때문에 초반 설계에 공수가 필요하고, 이후 구조 수정에 어려움이 따를 수 있다.
Immer의 사용 여부
Immer는 일시적으로 불변 객체를 변경 가능하도록 해준다.
Redux는 기본적으로 Immer를 사용하지만, Zustand를 사용하지 않는다.
Zustand에서 Immer를 사용할 수는 있다.
상태 전파
Redux는 컨텍스트를 사용하지만, Zustand는 모듈 임포트를 사용한다.
데이터 흐름
Redux는 Action을 Dispatch하는 단방향 데이터 흐름을 기반으로 한다.
하지만 Zustand의 경우, 데이터 흐름 측면에서 별다른 의견을 제시하지 않으며 개발자가 모든 것을 처리해야 한다.
✅ Redux는 풀소유라면, Zustand는 무소유다.
Zustand는 가벼운만큼 정해진 틀이 없는 것 같다.
딱 리액트를 사용하며 마이크로 상태 관리를 할 수 있도록 도와줄 수 있는 정도 그 이상도 이하도 아닌 것 같다.
따라서 초기 설계를 확실하게 잘한다면 정말 효과적으로 사용할 수 있을 것 같다.
하지만 어설프게 했다간 뜯어 고쳐야할 일이 생기지 않을까….
Jotai와 Recoil을 사용하는 시점
key 사용 여부
Jotai는 아톰 객체는 WeakMap의 참조로 실제 아톰 값을 가져온다.
반면 Recoil은 key 값을 통해 값을 가져온다.
Jotai를 개발하게 된 큰 동기 중 하나는 key 문자열 생략이라고 한다.
// recoil
atom({ key: 'textState', default: '' });
// jotai
atom('');
key는 고유해야하기 때문에 네이밍에 신경을 쓰는 것이 싫으셨다고 한다.
atom 함수
Jotai의 atom은 Recoil의 atom과 selector를 모두 대체한다.
하지만 표현하지 못하는 것이 있을 수도 있고, 별도의 함수를 필요로 할 수 있다(?).
Provider
Jotai의 공급자 제거 모드는 Provider를 생략할 수 있게 해준다.
✅ 이전까지는 크게 실감하지 못했었는데, key의 여부가 은근히 신경쓰이는 것 같다.
“하지만 표현하지 못하는 것이 있을 수도 있고, 별도의 함수를 필요로 할 수 있다.”
라는 표현이 아직 이해가 잘 가지 않는다.
하지만 bottom-up, top-down이 모두 가능한 Jotai가 표현 못하는 것이 있을까? 싶긴하다.
심지어 selector도 존재하니…
Valtio와 MobX 사용하기
철학은 다르지만 Valtio와 MobX가 꽤 비교되기도 한단다.
우선, 공통점은 둘 다 변경 가능한 상태 기반이다.
하지만 렌더링 최적화 방법에서 차이가 있다.
- Valtio - 훅 사용
- MobX - HOC
갱신 방식
MobX는 클래스 기반, Valtio는 객체 기반이다.
Valtio의 경우, 상태 객체에서 갱신 함수를 분리할 수 있다.
proxy 함수로 만든 상태 객체 외부에서 갱신 함수를 정의하여 코드 분할, 최소화, 불필요한 코드 제거로 번들 크기 최적화가 가능하다.
렌더링 최적화
MobX는 옵저버 방식인 반면, Valtio는 훅 방식을 택했다.
옵저버 방식은 예측 가능성이 높고, 훅 방식은 동시성 렌더링에 친화적이다.
✅ MobX는 우선 클래스 기반이기 때문에 함수형이 대세가 되어버린 리액트에서는 사용할 일이 없어보인다.
HOC와 동시성 렌더링은 가볍게만 알고 있는 개념들인데 다시 한번 찾아봐야겠다.
Zustand, Jotai, Valtio 비교하기
상태는 어디에 위치하는가?
- 모듈 상태 - Zustand, Valtio
- 컴포넌트 상태 - Jotai
컴포넌트 상태는 여러 Provider 아래에서 재사용하는 것이 가능하다.
하지만 모듈 상태는 이것을 위해 컨텍스트를 사용해야 할 것이다.
반대로 리액트 외부에서 컴포넌트 상태에 접근하는 것은 불가능하기 때문에 컴포넌트 상태에 연결하기 위해선 모듈 상태를 사용해야 할 가능성이 있다.
따라서 상황에 맞게 어떤 것을 사용할지 결정해서 쓰자.
상태 갱신 스타일은 무엇인가?
Zustand와 Valtio 사이에는 큰 차이점이 없다.
Zustand는 불변 상태 모델을 기반으로 하는 반면, Valtio는 변경 가능한 상태 모델을 기반으로 한다.
불변 상태 모델의 장점은 객체 참조(메모리 주소)를 비교하여 변경 사항이 있는지 파악할 수 있다.
리액트 자체도 불변 상태 모델을 기반으로 하기 때문에 Zustand는 호환성이 좋고 상당히 가벼운 라이브러리이다.
✅ Valtio도 변경 가능 상태 모델이지만, Proxy를 활용한 방식으로 충분히 사용에 고려할만하다고 생각한다.
객체 참조가 압도적으로 좋긴 하겠지만, 어차피 머신의 성능은 계속 올라가고 있기 때문에 가면 갈수록 격차가 줄어들 것이라고 생각하기 때문이다.
심지어 가변 상태로 인해 코드가 짧아질 수 있고, 이에 따른 가독성까지 확보할 수 있기도 하다.
Zustand만 장점을 써놓으셔서 Valtio도 대신 어필을 해봤다.
도은
Zustand, Jotai, Valtio 비교하기
상태가 어디에 위치하는가?
Zustand
,Valtio
: 모듈 상태를 기반으로 설계Jotai
: 컴포넌트 상태를 기반으로 설계
🤔 모듈 상태 기반 vs 컴포넌트 상태 기반
모듈 상태 기반 설계
: 애플리케이션의 상태를 중앙에서 관리하는 방식- 장점: 상태 업데이트 로직이 분산되지 않아 관리가 용이
- 단점: 컴포넌트 상태 기반보다는 러닝커브가 있는 것 같음
컴포넌트 상태 기반 설계
: 각 컴포넌트 내에서 상태를 관리하는 방식- 장점: 단순성: 각 컴포넌트는 자신의 상태를 직접 관리 → 상태 로직이 분산되어 있어 개별 컴포넌트의 복잡성 감소.
- 단점: 상태를 컴포넌트 별로 관리할 수 있기 때문에 동일한 상태가 전역 곳곳에 숨어있을 수 있음
상태 갱신 스타일은 무엇인가?
Zustand
: 불변 상태 모델 기반Valtio
: 변경 가능한 상태 모델 기반