예전에 proxy-compare라는 녀석과 context api를 활용해서 간단한 상태관리 툴을 만들었었는데, 내가 만들고 싶었던 궁극체(?)느낌의 프로젝트가 이미 존재했다. 바로 valtio라는 녀석이다.
이 글은 아주 짧게 valtio의 장점과 동작원리만 간단하게 소개하고싶다. 그래야 다른 사람들도 많이 쓸 것 같다
Valtio, makes proxy-state simple for React and Vanilla
valtio는 zustand를 만든 Poimandres 오픈소스 그룹에서 만든 상태관리 라이브러리이다. 리액트 생태계에 있는 대부분의 상태관리 툴은 이쪽에서 만든다고 봐도 무방하다.
이것만으로도 valtio를 쓸만하다.
const counterStore = proxy({ count: 0, text: "hello" });
const Counter: React.FC<CounterProps> = () => {
const { count } = useSnapshot(counterStore);
return (
<View>
<Text>Counter: {count}</Text>
</View>
);
};
이렇게 구성된 컴포넌트라고 가정했을때, 참조를 count에 대해서만 하고 있기 때문에 그 외의 값이 바뀌어도 리랜더링이 일어나지 않는다. 다시말해 text에 어떤 값이 들어와도 리랜더되지 않는다. 그냥 이런식으로 스토어를 만들고 사용처에서는 참조하는 값만 신경써주면 자동적으로 랜더링이 최적화된다.
const counterStore = proxy({ count: 0, text: "hello" });
const Counter: React.FC<CounterProps> = () => {
const { count } = useSnapshot(counterStore);
return (
<View>
<Text>Counter: {count}</Text>
<Button title="increase" onPress={() => {
counterStore.count++;
}}/>
</View>
);
};
보통의 리액트라면 표시된 라인은 제대로 동작하지 않는다. 불변성을 해치기 때문이고 여러번 중첩된 복잡한 오브젝트의 경우 특정 벨류를 바꾸고자 할 때 불변성을 지켜주려면 상당한 노력이 드는데, 이를 immer로 해결하곤 했다. 그런데 valtio에서는 그냥 저렇게 사용하기만 하면 된다.
굳이 예를 들자면 사용시에 recoil
과 흡사하게 사용하면 된다.