Split
splitAtom
Section titled “splitAtom”splitAtom 工具函数适用于需要为列表中的每个元素获取独立原子的场景。它接受一个包含列表的读/写原子,返回一个原子,该原子持有一个原子列表,每个原子对应原始列表中的一个元素。
splitAtom 的简化类型签名如下:
type SplitAtom = <Item, Key>( arrayAtom: PrimitiveAtom<Array<Item>>, keyExtractor?: (item: Item) => Key): Atom<Array<PrimitiveAtom<Item>>>-
返回的原子在写方向上包含一个 dispatch 函数(自 v1.6.4 起),提供了一种简单的方式来修改原始原子,支持
remove、insert和move等操作。 -
可以提供可选的
keyExtractor函数作为第二个参数,以增强稳定性和性能。
Key Extractor
Section titled “Key Extractor”splitAtom 工具函数支持第二个参数,即 key 提取器函数:
export function splitAtom<Item, Key>( arrAtom: WritableAtom<Item[], [Item[]], void> | Atom<Item[]>, keyExtractor?: (item: Item) => Key,)keyExtractor 的重要注意事项:
- 如果
splitAtom在 React 渲染循环中使用,keyExtractor必须是保持对象相等性(浅相等)的稳定函数。此要求不适用于渲染循环之外。 - 提供
keyExtractor可以增强原子输出的稳定性(使记忆化更频繁地命中缓存)。它可以防止由于源数组中的索引移动导致的子原子不必要重建。 keyExtractor是可选的优化手段,仅在提取的 key 保证对数组中的每个元素唯一时才应使用。
以下是 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 管理待办事项列表,允许对每个条目进行独立操作,同时维护整体的列表原子。