jotai는 React 상태 관리 라이브러리로, 간단하면서도 강력한 상태 관리를 제공합니다. jotai는 "atoms"라는 단위 상태 객체를 중심으로 작동하며, Recoil과 비슷하지만 더 가볍고 사용하기 쉬운 것이 특징입니다.
단순함:
useState와 비슷한 API로 작동하여 쉽게 배울 수 있습니다.React 상태와 완벽한 통합:
useAtom 훅을 사용하여 상태를 읽고 업데이트할 수 있습니다.Fine-grained Re-renders:
Composable 상태:
타입스크립트 지원:
useState와 비슷한 역할을 합니다.atom을 사용해 상태를 정의하고 useAtom 훅으로 접근합니다.import { atom, useAtom } from "jotai";
// Atom 정의
const countAtom = atom(0);
const Counter = () => {
const [count, setCount] = useAtom(countAtom);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
</div>
);
};
import { atom, useAtom } from "jotai";
// 기본 atom
const countAtom = atom(0);
// 파생 상태 atom
const doubledCountAtom = atom((get) => get(countAtom) * 2);
const Counter = () => {
const [count, setCount] = useAtom(countAtom);
const [doubledCount] = useAtom(doubledCountAtom);
return (
<div>
<p>Count: {count}</p>
<p>Doubled Count: {doubledCount}</p>
<button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
</div>
);
};
atom 내부에서 Promise를 반환하여 데이터 로딩 상태를 처리합니다.import { atom, useAtom } from "jotai";
// 비동기 atom
const fetchUserAtom = atom(async () => {
const response = await fetch("https://api.example.com/user");
const user = await response.json();
return user;
});
const User = () => {
const [user] = useAtom(fetchUserAtom);
return <div>User: {user.name}</div>;
};
const countAtom = atom(0);
const doubledCountAtom = atom(
(get) => get(countAtom) * 2,
(get, set, newValue) => {
set(countAtom, newValue / 2); // countAtom 값을 업데이트
}
);
const Counter = () => {
const [doubledCount, setDoubledCount] = useAtom(doubledCountAtom);
return (
<div>
<p>Doubled Count: {doubledCount}</p>
<button onClick={() => setDoubledCount(10)}>Set to 10</button>
</div>
);
};
2.10.1은 Jotai의 최신 안정 버전 중 하나로, 아래와 같은 주요 특징을 포함합니다:
1. React 18 지원:
| Feature | Jotai | Redux | Recoil |
|---|---|---|---|
| Learning Curve | 쉬움 | 중간 | 중간 |
| Boilerplate | 거의 없음 | 많음 | 적음 |
| 상태 구독 | 세밀한 구독 | 전체 리렌더링 | 세밀한 구독 |
| React와의 통합 | 뛰어남 | 뛰어남 | 뛰어남 |
| 비동기 데이터 관리 | 쉬움 | Middleware 필요 | 쉬움 |
| TypeScript 지원 | 뛰어남 | 뛰어남 | 뛰어남 |
Jotai는 React의 기본 상태 관리와 유사하면서도 전역 상태 관리에 더 적합한 옵션을 제공합니다. 성능 최적화와 간단함이 중요한 프로젝트에서 특히 유용합니다.
Jotai는 atom을 사용해 상태를 정의하고, React 컴포넌트에서 useAtom을 사용해 상태를 읽거나 업데이트합니다. 추가로 Jotai는 파생 상태, 비동기 상태, 커스텀 스토어 등을 지원하며, 이를 통해 상태 관리의 유연성을 제공합니다.
atomatom은 Jotai의 상태 단위입니다. React의 useState와 비슷하지만 글로벌로 사용할 수 있습니다.
import { atom, useAtom } from "jotai";
// Atom 정의
const countAtom = atom(0);
const Counter = () => {
const [count, setCount] = useAtom(countAtom);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
</div>
);
};
atom은 상태를 저장하는 최소 단위입니다.useAtom을 통해 atom을 읽고(setter 포함) 업데이트할 수 있습니다.const countAtom = atom(0);
const doubleCountAtom = atom((get) => get(countAtom) * 2);
const Counter = () => {
const [count, setCount] = useAtom(countAtom);
const [doubleCount] = useAtom(doubleCountAtom);
return (
<div>
<p>Count: {count}</p>
<p>Double Count: {doubleCount}</p>
<button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
</div>
);
};
const userAtom = atom(async () => {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
return await response.json();
});
const User = () => {
const [user] = useAtom(userAtom);
return <div>User: {user.name}</div>;
};
getDefaultStoreJotai는 상태를 관리하기 위해 Store를 사용합니다. 일반적으로는 기본 Store를 사용하며, getDefaultStore를 통해 이 기본 Store에 접근할 수 있습니다.
import { atom, getDefaultStore } from "jotai";
// Atom 정의
const countAtom = atom(0);
// 기본 Store 가져오기
const defaultStore = getDefaultStore();
// Store에서 직접 상태 읽기/업데이트
console.log(defaultStore.get(countAtom)); // 0
defaultStore.set(countAtom, 10); // 상태 업데이트
console.log(defaultStore.get(countAtom)); // 10
get(atom)set(atom, value)jotai/utilsJotai의 유틸리티 라이브러리로, 상태 관리 작업을 더 쉽게 해주는 여러 가지 도구를 제공합니다.
atomWithStoragelocalStorage 또는 sessionStorage와 동기화.import { atomWithStorage } from "jotai/utils";
// localStorage와 동기화된 atom 생성
const themeAtom = atomWithStorage("theme", "light");
const ThemeSwitcher = () => {
const [theme, setTheme] = useAtom(themeAtom);
return (
<button onClick={() => setTheme((prev) => (prev === "light" ? "dark" : "light"))}>
Current Theme: {theme}
</button>
);
};
atomWithDefaultimport { atomWithDefault } from "jotai/utils";
const baseCountAtom = atom(5);
const doubleBaseAtom = atomWithDefault((get) => get(baseCountAtom) * 2);
const Counter = () => {
const [doubleBase, setDoubleBase] = useAtom(doubleBaseAtom);
return (
<div>
<p>Double Base: {doubleBase}</p>
<button onClick={() => setDoubleBase(20)}>Set to 20</button>
</div>
);
};
splitAtomimport { splitAtom } from "jotai/utils";
const listAtom = atom(["apple", "banana", "cherry"]);
const itemAtoms = splitAtom(listAtom);
const List = () => {
const [items] = useAtom(itemAtoms);
return (
<ul>
{items.map((itemAtom) => (
<Item key={itemAtom} atom={itemAtom} />
))}
</ul>
);
};
const Item = ({ atom }) => {
const [item, setItem] = useAtom(atom);
return <li onClick={() => setItem("clicked")}>{item}</li>;
};
atomFamilyimport { atomFamily } from "jotai/utils";
const countFamily = atomFamily((param) => atom(param));
const Counter = ({ id }) => {
const [count, setCount] = useAtom(countFamily(id));
return (
<div>
<p>Count {id}: {count}</p>
<button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
</div>
);
};
atomWithStorage: 상태를 브라우저 저장소와 동기화.atomWithDefault: 기본값 계산 로직을 간결하게 정의.splitAtom: 배열이나 객체를 효율적으로 관리.atomFamily: 동적으로 Atom을 생성하여 확장성 있는 상태 관리.atom: Jotai의 상태 단위.getDefaultStore: Jotai의 기본 Store를 가져와 상태를 직접 관리.jotai/utils: 강력한 유틸리티로 상태 동기화, 파생 상태, 배열 관리 등을 지원.이러한 도구를 활용하면 Jotai를 더욱 효율적이고 유연하게 사용할 수 있습니다. 필요에 따라 utils나 커스텀 로직을 작성해 상태 관리를 최적화하세요!