JotaiJotai

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

Split

splitAtom

splitAtom 유틸리티는 리스트의 각 요소에 대한 아톰을 얻어야 하는 상황에서 사용됩니다. 이 유틸리티는 리스트를 포함하는 읽기/쓰기 아톰에서 동작하며, 원본 리스트의 각 항목에 해당하는 아톰들을 담은 리스트를 반환합니다.

시그니처

splitAtom의 간소화된 타입 시그니처는 다음과 같습니다:

type SplitAtom = <Item, Key>(
arrayAtom: PrimitiveAtom<Array<Item>>,
keyExtractor?: (item: Item) => Key
): Atom<Array<PrimitiveAtom<Item>>>

주요 기능

  1. 반환된 아톰은 write 방향으로 디스패치 함수를 포함합니다(v1.6.4부터). 이를 통해 remove, insert, move와 같은 액션으로 원본 아톰을 간단히 수정할 수 있습니다.

  2. 안정성과 성능을 높이기 위해 두 번째 인자로 선택적 keyExtractor 함수를 제공할 수 있습니다.

키 추출기

splitAtom 유틸리티는 두 번째 인자로 키 추출 함수를 지원합니다:

export function splitAtom<Item, Key>(
arrAtom: WritableAtom<Item[], [Item[]], void> | Atom<Item[]>,
keyExtractor?: (item: Item) => Key,
)

keyExtractor에 대한 중요한 고려사항:

  • splitAtom이 React 렌더링 루프 내에서 사용될 경우, keyExtractor는 객체 동등성(얕은 비교)을 유지하는 안정적인 함수여야 합니다. 이 요구사항은 렌더링 루프 외부에서는 적용되지 않습니다.
  • keyExtractor를 제공하면 atom 출력의 안정성이 향상됩니다(이로 인해 메모이제이션이 더 자주 캐시를 적중합니다). 이는 소스 배열의 인덱스 이동으로 인한 불필요한 서브 atom 재생성을 방지합니다.
  • keyExtractor는 배열 내 각 항목에 대해 추출된 키가 고유함이 보장될 때만 사용해야 하는 선택적 최적화입니다.

예제 사용법

다음은 splitAtom을 사용하는 예제입니다:

import { Provider, atom, useAtom, PrimitiveAtom } from 'jotai'
import { splitAtom } from 'jotai/utils'
import './styles.css'
const initialState = [
{
task: 'help the town',
done: false,
},
{
task: 'feed the dragon',
done: false,
},
]
const todosAtom = atom(initialState)
const todoAtomsAtom = splitAtom(todosAtom)
type TodoType = (typeof initialState)[number]
const TodoItem = ({
todoAtom,
remove,
}: {
todoAtom: PrimitiveAtom<TodoType>
remove: () => void
}) => {
const [todo, setTodo] = useAtom(todoAtom)
return (
<div>
<input
value={todo.task}
onChange={(e) => {
setTodo((oldValue) => ({ ...oldValue, task: e.target.value }))
}}
/>
<input
type="checkbox"
checked={todo.done}
onChange={() => {
setTodo((oldValue) => ({ ...oldValue, done: !oldValue.done }))
}}
/>
<button onClick={remove}>remove</button>
</div>
)
}
const TodoList = () => {
const [todoAtoms, dispatch] = useAtom(todoAtomsAtom)
return (
<ul>
{todoAtoms.map((todoAtom) => (
<TodoItem
todoAtom={todoAtom}
remove={() => dispatch({ type: 'remove', atom: todoAtom })}
/>
))}
</ul>
)
}
const App = () => (
<Provider>
<TodoList />
</Provider>
)
export default App

이 예제는 splitAtom을 사용하여 할 일 목록을 관리하는 방법을 보여줍니다. 각 항목을 개별적으로 조작하면서도 전체 목록 아톰을 유지할 수 있습니다.