Skip to content

Latest commit

History

History
94 lines (79 loc) 路 2.1 KB

split-atom.mdx

File metadata and controls

94 lines (79 loc) 路 2.1 KB
title
splitAtom

The splitAtom utility is useful for when you want to get an atom for each element in a list. It works for read/write atoms that contain a list. When used on such an atom, it returns an atom which itself contains a list of atoms, each corresponding to the respective item in the original list.

A simplified type signature would be:

type SplitAtom = <Item>(arrayAtom: PrimitiveAtom<Array<Item>>): Atom<Array<PrimitiveAtom<Item>>>

Additionally, the atom returned by splitAtom contains a dispatch function in the write direction (since v1.6.4), this is useful for when you want a simple way to modify the original atom with actions such as remove, insert, and move.

See the below example for usage.

codesandbox

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