Skip to content

Latest commit

History

History
75 lines (61 loc) 路 1.79 KB

wait-for-all.mdx

File metadata and controls

75 lines (61 loc) 路 1.79 KB
title
waitForAll

Sometimes you have multiple async atoms in your components:

const dogsAtom = atom(async (get) => {
  const response = await fetch('/dogs')
  return await response.json()
})
const catsAtom = atom(async (get) => {
  const response = await fetch('/cats')
  return await response.json()
})

const App = () => {
  const [dogs] = useAtom(dogsAtom)
  const [cats] = useAtom(catsAtom)
  // ...
}

However, this will start fetching one at the time, which is not optimal - It would be better if we can start fetching both as soon as possible.

The waitForAll utility is a concurrency helper, which allows us to evaluate multiple async atoms:

const dogsAtom = atom(async (get) => {
  const response = await fetch('/dogs')
  return await response.json()
})
const catsAtom = atom(async (get) => {
  const response = await fetch('/cats')
  return await response.json()
})

const App = () => {
  const [[dogs, cats]] = useAtom(waitForAll([dogsAtom, catsAtom]))
  // or ...
  const [dogs, cats] = useAtomValue(waitForAll([dogsAtom, catsAtom]))
  // ...
}

You can also use waitForAll inside an atom - It's also possible to name them for readability:

const dogsAtom = atom(async (get) => {
  const response = await fetch('/dogs')
  return await response.json()
})
const catsAtom = atom(async (get) => {
  const response = await fetch('/cats')
  return await response.json()
})

const animalsAtom = waitForAll({
  dogs: dogsAtom,
  cats: catsAtom,
})

const App = () => {
  const [{ dogs, cats }] = useAtom(animalsAtom)
  // or ...
  const { dogs, cats } = useAtomValue(animalsAtom)
  // ...
}

Note: If you use an object in waitForAll and waitForAll is inside render function, you need to wrap it with useMemo to avoid infinite loop.

Codesandbox