Large objects
아래 예제와 설명은 codesandbox를 기반으로 합니다. 이 예제들을 따라가면서 코드샌드박스를 확인하면 더 잘 이해할 수 있습니다.
때로는 중첩된 데이터를 아톰에 저장해야 할 때가 있습니다. 그리고 그 데이터를 다른 수준에서 변경하거나, 모든 변경 사항을 듣지 않고도 데이터의 일부만 사용해야 할 때가 있습니다.
다음 예제를 살펴보겠습니다:
const initialData = {people: [{name: 'Luke Skywalker',information: { height: 172 },siblings: ['John Skywalker', 'Doe Skywalker'],},{name: 'C-3PO',information: { height: 167 },siblings: ['John Doe', 'Doe John'],},],films: [{title: 'A New Hope',planets: ['Tatooine', 'Alderaan'],},{title: 'The Empire Strikes Back',planets: ['Hoth'],},],info: {tags: ['People', 'Films', 'Planets', 'Titles'],},}
focusAtom
focusAtom
은 여러분이 전달한 포커스를 기반으로 새로운 아톰을 생성합니다. jotai-optics
이 유틸리티를 사용하면 아톰에 포커스를 맞추고 데이터의 특정 부분에서 아톰을 생성할 수 있습니다. 예를 들어, 위 데이터의 people
속성을 사용해야 할 때 다음과 같이 할 수 있습니다:
import { atom } from 'jotai'import { focusAtom } from 'jotai-optics'const dataAtom = atom(initialData)const peopleAtom = focusAtom(dataAtom, (optic) => optic.prop('people'))
focusAtom
은 WritableAtom
을 반환합니다. 이는 peopleAtom
의 데이터를 변경할 수 있다는 것을 의미합니다.
위 데이터 예제에서 films
속성을 변경하더라도 peopleAtom
은 리렌더링을 일으키지 않습니다. 이것이 focusAtom
을 사용하는 장점 중 하나입니다.
splitAtom
splitAtom
유틸리티는 리스트의 각 요소에 대한 아톰을 얻고 싶을 때 유용합니다. jotai/utils
이 유틸리티는 배열을 값으로 반환하는 아톰에 사용합니다. 예를 들어, 앞서 만든 peopleAtom
은 사람들의 속성 배열을 반환하므로, 그 배열의 각 항목에 대한 아톰을 반환할 수 있습니다. 배열 아톰이 쓰기 가능하다면, splitAtom
이 반환한 아톰도 쓰기 가능합니다. 배열 아톰이 읽기 전용이라면, 반환된 아톰도 읽기 전용입니다.
import { splitAtom } from 'jotai/utils'const peopleAtomsAtom = splitAtom(peopleAtom)
이렇게 컴포넌트에서 사용할 수 있습니다.
const People = () => {const [peopleAtoms] = useAtom(peopleAtomsAtom)return (<div>{peopleAtoms.map((personAtom) => (<Person personAtom={personAtom} key={`${personAtom}`} />))}</div>)}
selectAtom
이 함수는 원본 atom의 값을 기반으로 파생된 atom을 생성합니다. jotai/utils
이 유틸리티는 focusAtom
과 비슷하지만 항상 읽기 전용 atom을 반환합니다.
info 데이터를 사용하고 싶은데, 이 데이터가 항상 변경되지 않는다고 가정해 봅시다. 이 데이터로부터 읽기 전용 atom을 만들고, 생성된 atom을 선택할 수 있습니다.
// 먼저 initialData.info를 기반으로 파생된 atom을 생성합니다.const infoAtom = atom((get) => get(dataAtom).info)
그런 다음 컴포넌트에서 이 atom을 사용합니다:
import { atom, useAtom } from 'jotai'import { selectAtom, splitAtom } from 'jotai/utils'const tagsSelector = (s) => s.tagsconst Tags = () => {const tagsAtom = selectAtom(infoAtom, tagsSelector)const tagsAtomsAtom = splitAtom(tagsAtom)const [tagAtoms] = useAtom(tagsAtomsAtom)return (<div>{tagAtoms.map((tagAtom) => (<Tag key={`${tagAtom}`} tagAtom={tagAtom} />))}</div>)}