JotaiJotai

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

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'))

focusAtomWritableAtom을 반환합니다. 이는 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.tags
const 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>
)
}