Jotai 는 상태라는 뜻의 일본어로
Zustand 를 만든 곳에서 만든 상태 관리 라이브러리
Zustand 는 독일어로 상태
Zustand 는 Redux를 대체하기 위해
Jotai 는 Recoil 을 대체하기 위해 만들었다고 한다
Jotai 는 Recoil 과 거의 흡사한데
atom 에 key 를 주지 않아 조금 더 단순한 코드를 작성할 수 있다
큰 차이는 없는듯..
리코일 개발자가 퇴사했다고 해서 다들 한 번쯤 해보지 않을까 싶다
import { atom } from 'jotai'
const numberAtom = atom(10) // 초기값을 제공하여 numberAtom 정의
아톰은 데이터를 정의하는 것이고
값을 보유하지 않는다
값은 store 에 존재하게 된다
초기값을 제공하여 primitive atom 을 생성할 수 있다
const [number, setNumber] = useAtom(numberAtom)
atom 에서 정의한 numberAtom 의 값과 set 함수를 얻는다
React 의 state 와 같이 사용할 수 있다
세 가지 패턴의 파생 atom 을 만들 수 있다
const readOnlyAtom = atom((get) => get(priceAtom) * 2)
const writeOnlyAtom = atom(
null, // it's a convention to pass `null` for the first argument
(get, set, update) => {
// `update` is any single value we receive for updating this atom
set(priceAtom, get(priceAtom) - update.discount)
}
)
const readWriteAtom = atom(
(get) => get(priceAtom) * 2,
(get, set, newPrice) => {
set(priceAtom, newPrice / 2)
// you can set as many atoms as you want at the same time
}
)
아래와 같이 사용할 수도 있음
const [derivedAtomValue] = useAtom(
useMemo(
() => atom((get) => get(numberAtom) * 2),
[]
)
)
파생 아톰을 쓸 일이 얼마나 될까 싶다..
useAtom hook 은 Provider 에 저장된 값을 읽어온다
react 의 useState hook 처럼 값, 업데이트 함수를 반환한다
처음 Provider 는 자체적으로 아무 값도 갖지 않는다
atom 을 통해 초기 값을 정의하고
useAtom 이 사용되면 Provider 에 초기 값을 추가한다
atom 이 파생 아톰이면 read 함수가 실행되어 초기 값을 계산한다
atom 이 더이상 사용되지 않으면 (atom 을 사용하는 모든 컴포넌트가 마운트 해제되어 atom 구성이 존재하지 않을 시) 값이 Provider 에서 제거된다
const Root = () => (
<Provider>
<App />
</Provider>
)
atom 에는 값이 없다 (아톰은 정의만)
atom 값은 별도의 store (저장소) 에 저장되는데
provider 는 store 를 포함하고
컴포넌트 트리에 atom 값을 제공한다
provider 는 React 의 Context 처럼 작동한다
Provider 를 사용하지 않으면 defaultStore 가 제공되고
Provider-less 모드로 작동한다
서로 다른 컴포넌트에서 같은 atom 을 사용하려면 Provider 를 사용해야 하고
Provider-less 모드라면 atom 이 해당 컴포넌트에서만 유효한 것 같다
provider 는 store 를 prop 으로 받을 수 있다
Provider 는 기본적으로 store 를 포함하는 개념인 것 같지만
하위 트리에서 사용할 수 있는 Store 를 따로 생성하여
useStore hook 으로 저장소를 사용할 수 있다
const myStore = createStore()
const Root = () => (
<Provider store={myStore}>
<App />
</Provider>
)
const Component = () => {
const store = useStore()
// ...
}