Jotai
작성일 : 2024.12.08
Jotai란?
Jotai는 React를 위한 상태 관리 라이브러리로, 매우 작은 크기(3kb)와 TypeScript 지향적인 설계가 특징입니다. React.js, Next.js, React Native 등 다양한 React 기반 프레임워크에서 사용할 수 있으며, 특히 re-rendering 문제를 효과적으로 해결했다는 점이 주목할 만합니다.
Jotai의 주요 특징
- 매우 가볍고 간단한 API (3kb의 번들 사이즈)
- TypeScript로 작성되어 타입 안정성이 뛰어남
- React Suspense와 완벽한 통합
- 중첩된 업데이트 최적화
- Redux DevTools 지원
설치 방법
npm install jotai
# 또는
yarn add jotai
Primitive Atom 이해하기
Primitive atom은 Jotai의 가장 기본적인 구성 요소입니다. "Primitive"라는 말 그대로 "원시적인", "기본적인" atom이라는 의미입니다.
주요 특징:
- 가장 단순한 형태의 atom
- 단일 값을 저장할 수 있음 (숫자, 문자열, 객체 등)
- 읽기와 쓰기가 모두 가능
- 반드시 초기값이 필요
// primitive atom의 예시들
const numberAtom = atom(0); // 숫자
const stringAtom = atom("hello"); // 문자열
const booleanAtom = atom(true); // 불리언
const objectAtom = atom({ name: "John", age: 25 }); // 객체
이는 다른 atom들(예: 파생된 atom)의 기초가 되며, 가장 흔하게 사용되는 형태입니다.
기본 사용법
1. 기본 atom 생성과 사용
import { atom, useAtom } from "jotai";
// atom 생성
const countAtom = atom(0);
function Counter() {
// atom 사용
const [count, setCount] = useAtom(countAtom);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
2. Atom 사용을 위한 다양한 훅
Jotai는 상황에 따라 최적화된 여러 훅을 제공합니다:
// 읽기/쓰기 모두 필요할 때
const [value, setValue] = useAtom(myAtom);
// 읽기만 필요할 때 (최적화)
const value = useAtomValue(myAtom);
// 쓰기만 필요할 때 (최적화)
const setValue = useSetAtom(myAtom);
3. 파생된(Derived) Atom
다른 atom의 값을 기반으로 새로운 값을 계산할 수 있습니다:
const countAtom = atom(0);
// 읽기 전용 파생 atom
const doubleCountAtom = atom((get) => get(countAtom) * 2);
// 읽기/쓰기 가능한 파생 atom
const countryAtom = atom("Japan");
const citiesAtom = atom(
(get) => getCities(get(countryAtom)),
(get, set, newCity) => {
set(countryAtom, getCountry(newCity));
}
);
4. 비동기 Atom
비동기 데이터 처리도 쉽게 할 수 있습니다:
const userAtom = atom(async () => {
const response = await fetch("/api/user");
return response.json();
});
function UserInfo() {
const [user] = useAtom(userAtom);
if (user.loading) return <Loading />;
return <div>{user.name}</div>;
}
5. Provider를 통한 상태 관리
기본 Provider
import { Provider } from "jotai";
function App() {
return (
<Provider>
<Counter />
<OtherComponent />
</Provider>
);
}
커스텀 Provider와 상태 하이드레이션
import { useHydrateAtoms } from "jotai/utils";
function JotaiProvider({ children, initialState }) {
useHydrateAtoms([
[nameAtom, initialState.name],
[ageAtom, initialState.age],
]);
return children;
}
6. atomWithStorage로 영구 저장소 활용
브라우저의 localStorage와 연동하여 상태를 영구적으로 저장할 수 있습니다:
import { atomWithStorage } from "jotai/utils";
export const isLoginAtom = atomWithStorage("isLogin", false);
// 사용 예시
const MobileNav = () => {
const isLogin = useAtomValue(isLoginAtom);
const setIsLogin = useSetAtom(isLoginAtom);
const logoutAction = async (e) => {
const result = await handleLogout();
if (result.code < 400) {
setIsLogin(false); // localStorage에 자동 저장
}
};
};
장단점
장점
- 매우 작은 번들 사이즈
- 간단하고 직관적인 API
- TypeScript 지원이 뛰어남
- React의 기본 원칙을 잘 따름
- re-rendering 최적화가 잘 되어있음
단점
- 공식 문서가 다소 불친절할 수 있음
- 일부 고급 기능에 대한 설명이 부족
마치며
Jotai는 React 생태계에서 점점 더 중요한 위치를 차지하고 있는 상태 관리 라이브러리입니다. 특히 작은 번들 사이즈와 타입스크립트 친화적인 설계, 그리고 직관적인 API는 많은 개발자들에게 매력적인 선택지가 되고 있습니다.