JotaiJotai

상태
React를 위한 기본적이고 유연한 상태 관리

atomWithRefreshAndDefault

이 내용은 atomWithDefault의 다른 구현을 위한 것입니다.

atomWithDefault 동작 다시 보기

atomWithDefault 섹션의 예제 코드에서 볼 수 있듯이, count2Atom = atomWithDefault((get) => get(count1Atom) * 2)와 같이 생성된 후 업데이트하면 두 atom 간의 관계가 끊어집니다. 어떤 일이 발생했는지 확인해 보겠습니다.

    1. "increment count1"을 클릭하면, count1은 2가 되고 count2는 4가 됩니다.
    1. "increment count2"를 클릭하면, count1은 2로 유지되고 count2는 5가 됩니다. (관계가 끊어짐!!)

이제 이 두 atom은 count2Atom을 업데이트한 후 더 이상 관계가 없습니다. 따라서,

  • "increment count1"을 클릭하면 count1만 증가합니다.
  • count2Atom을 리셋하더라도 이 의존성 관계는 다시 복구되지 않습니다.

동기

특정 상황에서 다음과 같은 요구사항이 있을 수 있습니다.

  • 연결이 끊어지고 재설정된 후, 원래의 관계로 돌아가야 할 때
  • 파생된 아톰이 원본 아톰이 업데이트된 것을 기반으로 재설정되어야 할 때
  • 모든 파생 아톰을 재설정하고 싶지만 가능한 한 간단하게 동작하길 원할 때

이러한 경우를 어떻게 처리할 수 있을까요?
여기서는 atomWithDefault 대신 새로고침 가능한 아톰을 제공하는 함수를 선언적으로 생성하는 방법을 소개합니다.

const refreshCountAtom = atom(0)
const baseDataAtom = atom(1) // 원본 데이터, 예: base count1Atom
const dataAtom = atom(
(get) => {
get(refreshCountAtom) // atomWithRefresh에서 도입됨
return get(baseDataAtom)
},
(get, set, update) => {
set(baseDataAtom, update)
},
)
const atomWithRefreshAndDefault = (refreshAtom, getDefault) => {
const overwrittenAtom = atom(null)
return atom(
(get) => {
const lastState = get(overwrittenAtom)
if (lastState && lastState.refresh === get(refreshAtom)) {
return lastState.value
}
return getDefault(get)
},
(get, set, update) => {
set(overwrittenAtom, { refresh: get(refreshAtom), value: update })
},
)
}
// `atomWithDefault((get) => get(count1Atom) * 2)`의 대안
const refreshableAtom = atomWithRefreshAndDefault(
refreshCountAtom,
(get) => get(dataAtom) * 2,
)
// 하나의 아톰만 업데이트하여 재설정 가능
const resetRootAtom = atom(null, (get, set) => {
set(refreshCountAtom, get(refreshCountAtom) + 1)
})