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는 파생 상태, 비동기 상태, 커스텀 스토어 등을 지원하며, 이를 통해 상태 관리의 유연성을 제공합니다.
atom
atom
은 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>;
};
getDefaultStore
Jotai는 상태를 관리하기 위해 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/utils
Jotai의 유틸리티 라이브러리로, 상태 관리 작업을 더 쉽게 해주는 여러 가지 도구를 제공합니다.
atomWithStorage
localStorage
또는 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>
);
};
atomWithDefault
import { 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>
);
};
splitAtom
import { 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>;
};
atomFamily
import { 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
나 커스텀 로직을 작성해 상태 관리를 최적화하세요!