Atom Creators

An atom creator means simply a function that returns an atom or a set of atoms. It's just a function and it's not some features that the library provides, but it's an important pattern to make a fairly complex use case. This avoids the boilerplate of having to set up another atom just to update the state of the first.

Consider this case,

const fooAtom = atom(0); const barAtom = atom(0); const incFooAtom = atom(null, (get, set) => { set(fooAtom, c => c + 1); }; const incBarAtom = atom(null, (get, set) => { set(barAtom, c => c + 1); };

Although you can attach the suitable actions to the setter of the respective atom, but this also increases boilerplate code when there are more atoms in your code.

const incAllAtom = atom(null, (get, set, action) => { if(action === 'inc1') // increase first atom if(action === 'inc2') // increase second atom ... }

So simply replace this with the atom creators function.

const createCountIncAtoms = (initialValue) => { const baseAtom = atom(initialValue) const valueAtom = atom((get) => get(baseAtom)) const incAtom = atom(null, (get, set) => set(baseAtom, (c) => c + 1)) return [valueAtom, incAtom] }
import { atom, useAtom } from 'jotai'

const createCountIncAtoms = (initialValue) => {
  const baseAtom = atom(initialValue)
  const valueAtom = atom((get) => get(baseAtom))
  const incAtom = atom(null, (get, set) => set(baseAtom, (c) => c + 1))
  return [valueAtom, incAtom]
}

const [fooAtom, fooIncAtom] = createCountIncAtoms(0)
const [barAtom, barIncAtom] = createCountIncAtoms(0)

function App() {
  const [fooCount] = useAtom(fooAtom)
  const [, incFoo] = useAtom(fooIncAtom)
  const [barCount] = useAtom(barAtom)
  const [, incBar] = useAtom(barIncAtom)

  const onClick1 = () => {
    incFoo()
  }
  
  const onClick2 = () => {
    incBar()
  }

  return (
    <div className="app">
      <div>
        <span>{fooCount}</span>
        <button onClick={onClick1}>incFoo</button>
      </div>
      <div>
        <span>{barCount}</span>
        <button onClick={onClick2}>incBar</button>
      </div>
    </div>
  )
}

export default App
Open on CodeSandbox