상태 관리 라이브러리로 자주 사용하던 recoil 이 업데이트가 이뤄지지 않아,
마이그레이션할 라이브러리들을 찾던 중 후보에 있던 jotai 에 대해 정리해보고자 합니다.
React 생태계에는 수많은 상태 관리 라이브러리가 존재합니다. 그 중 가장 작고, 단순하며, 선언적 접근을 지향하는. 단순함에 집중한 미니멀리즘 상태 관리 라이브러리 Jotai 는 일본어 “状態(じょうたい, jotai)”에서 온 말로, ‘상태’ 자체를 최소 단위(atom)로 다루는 방식이 특징입니다.
왜 Jotai 인가? 라고 생각했을 때, 다음과 같은 장점들이 있습니다.
첫 번쨰, Jotai는 atom + hooks 만 이해하면 처음부터 끝까지 사용할 수 있어 러닝커브가 작습니다.
상태의 최소 단위를 나타내는 atom, atom 을 읽고 쓰는 훅인 useAtom 이 단순함 덕분에
"상태 관리를 위한 프레임워크"가 아니라 React 훅을 확장한 느낌으로 바로 받아들일 수 있습니다.
두 번쨰, Jotai는 불필요한 리렌더 최소화에 강점이 있습니다.
구독 기반 구조를 채택하여 컴포넌트는 자신이 직접 읽는 atom이 변경될 때만 렌더링됩니다.
불필요한 렌더링이 잦은 Redux Context 기반 접근보다 성능 면에서 유리할 수 있습니다.
세 번쨰, Jotai는 컴포지션에 친화적입니다.
atom 은 다른 atom을 참조하여 파생 상태(derived state) 를 만들 수 있습니다.
useMemo처럼 별도 최적화 코드를 작성할 필요 없이 "상태 간 관계"를 선언적으로 구축하는 방식입니다.
먼저 jotai 는 provider, root 없이 사용 가능합니다. 다만, 페이지별 혹은 컴포넌트별 상태를 격리해서 관리하고 싶을 경우,
SSR(서버 사이드 렌더링)을 더 안전하게 제어할 때(miss match 오류 등) Provider 를 사용할 수 있습니다.
provider 사용 예시
import { Provider } from 'jotai';
const App = () => (
<Provider>
<YourApp />
</Provider>
);
기본 atom 선언 예시
import { atom } from 'jotai';
// 디폴트 값이 0인 countAtom 선언
export const countAtom = atom(0);
// 타입 작성 시
export const countAtom2 = atom<number>(0);
기본 atom 사용 방법 예시
import { useAtom } from 'jotai';
import { countAtom, countAtom2 } from './atoms';
export default function Counter() {
// value 만 읽을 때 (useAtomValue)
const countValue = useAtomValue(countAtom2)
// set 함수만 사용할 때 (useSetAtom)
const setCountValue = useSetAtom(countAtom2)
// value 와 set 함수 모두 사용할 때 (useAtom)
const [count, setCount] = useAtom(countAtom);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>+</button>
</div>
);
}
다른 atom 을 읽어서(참조해서) 새로운 값을 계산해내는 Derived Atom 도 사용 가능합니다.
(derive atom 을 사용하는 이유는 복잡한 계산을 간단하게 하고, 성능 최적화를 위함입니다.)
// 위에 선언한 countAtom 을 참조하는 doubleCountAtom 선언
export const doubleCountAtom = atom(
(get) => get(countAtom) * 2
);
API 데이터를 로딩하는 atom을 만들 수도 있습니다. 이렇게 선언하면 컴포넌트에서 useAtom(userAtom)을 호출하는 순간 비동기 로직이 실행됩니다. (Suspense 처리로 깔끔하게 마무리 필요)
export const userAtom = atom(async () => {
const res = await fetch('/api/user');
return res.json();
});
jotai 는 단순하고 직관적인 API 덕분에 빠르게 상태 관리를 시작할 수 있는 라이브러리입니다.
뿐만 아니라 recoil 과 유사한 철학을 가지고 있어, recoil 에서 jotai 로의 마이그레이션도 비교적 수월한 편입니다.
페이지 단위의 독립 상태를 구성할 수 있고, 기존 Zustand/Redux와도 함께 사용할 수 있어 점진적인 도입이 가능합니다.
해당 블로그도 recoil 로 작성되어 있었으나, jotai 로 마이그레이션하였습니다.
아주 복잡한 도메인 모델을 다루는 경우가 아니라면,
대부분의 프론트엔드 프로젝트에서 가장 부담 없이 도입하고, recoil 을 대체하여 사용할 수 있는 상태 관리 도구라고 생각합니다.