Skip to main content
The useAtomValue hook reads an atom value and subscribes the component to re-render when the atom value changes. Use this hook when you only need to read the atom value and don’t need the setter function.

Signature

function useAtomValue<Value>(
  atom: Atom<Value>,
  options?: Options,
): Awaited<Value>

Type Definitions

type Options = {
  store?: Store
  delay?: number
  unstable_promiseStatus?: boolean
}

Parameters

atom
Atom<Value>
required
The atom to read. Can be any atom (primitive, derived, async).
options
Options
Optional configuration object.
options.store
Store
Custom store to use instead of the default Provider store.
options.delay
number
Delay in milliseconds before re-rendering when the atom value changes. Useful for debouncing updates or waiting for promises to potentially resolve.
options.unstable_promiseStatus
boolean
Enable promise status tracking. Defaults to true when React.use is not available (React < 19). When enabled, promises are augmented with status properties for better Suspense integration.

Returns

value
Awaited<Value>
The current value of the atom. If the atom’s value is a promise, it will be unwrapped using React Suspense (via React.use in React 19+ or a polyfill in earlier versions).

Examples

Basic Usage

import { atom, useAtomValue } from 'jotai'

const countAtom = atom(0)
const doubleAtom = atom((get) => get(countAtom) * 2)

function DoubleCount() {
  const double = useAtomValue(doubleAtom)

  return <div>Double: {double}</div>
}

With Async Atom

import { atom, useAtomValue } from 'jotai'
import { Suspense } from 'react'

const userAtom = atom(async () => {
  const response = await fetch('/api/user')
  return response.json()
})

function UserName() {
  const user = useAtomValue(userAtom)

  return <div>Hello, {user.name}!</div>
}

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <UserName />
    </Suspense>
  )
}

With Custom Store

import { atom, createStore, useAtomValue } from 'jotai'

const countAtom = atom(0)
const myStore = createStore()

function Count() {
  const count = useAtomValue(countAtom, { store: myStore })

  return <div>Count: {count}</div>
}

With Delay Option

import { atom, useAtomValue } from 'jotai'

const searchQueryAtom = atom('')

const searchResultsAtom = atom(async (get) => {
  const query = get(searchQueryAtom)
  const response = await fetch(`/api/search?q=${query}`)
  return response.json()
})

function SearchResults() {
  // Delay re-rendering by 200ms to reduce flashing during rapid updates
  const results = useAtomValue(searchResultsAtom, { delay: 200 })

  return (
    <div>
      {results.map((result) => (
        <div key={result.id}>{result.title}</div>
      ))}
    </div>
  )
}

Derived Atom Dependency

import { atom, useAtomValue, useSetAtom } from 'jotai'

const firstNameAtom = atom('John')
const lastNameAtom = atom('Doe')

const fullNameAtom = atom((get) => {
  return `${get(firstNameAtom)} ${get(lastNameAtom)}`
})

function Profile() {
  const fullName = useAtomValue(fullNameAtom)
  const setFirstName = useSetAtom(firstNameAtom)
  const setLastName = useSetAtom(lastNameAtom)

  return (
    <div>
      <p>Full Name: {fullName}</p>
      <input onChange={(e) => setFirstName(e.target.value)} />
      <input onChange={(e) => setLastName(e.target.value)} />
    </div>
  )
}

With AbortSignal

import { atom, useAtomValue } from 'jotai'
import { Suspense } from 'react'

const todoIdAtom = atom(1)

const todoAtom = atom(async (get, { signal }) => {
  const id = get(todoIdAtom)
  const response = await fetch(`/api/todos/${id}`, { signal })
  return response.json()
})

function Todo() {
  const todo = useAtomValue(todoAtom)

  return <div>{todo.title}</div>
}

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Todo />
    </Suspense>
  )
}

Notes

  • The component will re-render whenever the atom value changes
  • For async atoms, the component will suspend until the promise resolves
  • The hook uses React’s useDebugValue to display the atom value in React DevTools
  • When the atom or store changes, the component will re-render immediately with the new value
  • The delay option is useful for optimizing updates when you expect values to change rapidly
  • Promises are automatically aborted when dependencies change (via AbortSignal)

Build docs developers (and LLMs) love