Jotai — Estado Atômico
Atoms independentes, estado derivado com atomFamily, e integração com React Suspense.
Definição
Jotai é um gerenciador de estado atômico: cada atom é um pedaço independente de estado. Diferente do Zustand (um store), Jotai é bottom-up — componentes se subscrevem a atoms específicos. Atoms derivados (computed): atom((get) => get(aAtom) + get(bAtom)). atomFamily para atoms dinâmicos por ID. Integração nativa com Suspense para async atoms.
Problema → Solução
Problema
Zustand/Redux com um store global: qualquer componente pode escrever qualquer parte do estado acidentalmente. Estado muito granular exige muitos seletores. Atoms async com loading state manual.Solução
Jotai: cada atom é isolado. Componente só pode acessar atoms que importa explicitamente. Atom derivado é automaticamente memoizado. loadable() para async atoms sem Suspense. atomFamily para coleções (atom por ID de produto).Dica de entrevista
Tip
Jotai brilha para estado de UI muito granular e independente: abrir/fechar de N dropdowns, hover state de N items em lista, configurações por item. Onde Zustand tem um store centralizado, Jotai tem atoms distribuídos pelos componentes.Código
import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai'
import { atomFamily, loadable } from 'jotai/utils'
// Atom primitivo
const countAtom = atom(0)
// Atom derivado (read-only)
const doubleAtom = atom((get) => get(countAtom) * 2)
// Atom leitura+escrita com lógica
const incrementAtom = atom(
(get) => get(countAtom),
(get, set, by: number = 1) => set(countAtom, get(countAtom) + by)
)
// atomFamily — atom por ID
const productAtom = atomFamily((id: string) =>
atom(async () => {
const res = await fetch(`/api/products/${id}`)
return res.json()
})
)
// Async atom com Suspense
const userAtom = atom(async () => {
const res = await fetch('/api/user')
return res.json()
})
function UserName() {
const user = useAtomValue(userAtom) // Suspense automático
return <span>{user.name}</span>
}
// Granularidade: cada item tem seu próprio atom
function TodoItem({ id }: { id: string }) {
const [todo, setTodo] = useAtom(todoAtomFamily(id))
// só re-renderiza quando ESTE todo muda
return <input value={todo.text} onChange={e => setTodo({...todo, text: e.target.value})} />
}Perguntas de entrevista
Q.Jotai vs Zustand: quando escolher cada um?▾
A.Zustand: estado de domínio centralizado (cart, auth, produtos), quando você quer uma "fonte única de verdade" explícita. Jotai: estado granular de UI, atoms por ID (editando item específico), estado que é naturalmente derivado de outros. Muitos devs usam Zustand para domínio e Jotai para UI granular.
Q.Como funciona atom derivado no Jotai?▾
A.atom((get) => derivação): lê outros atoms via get(), Jotai rastreia dependências automaticamente. Quando qualquer atom lido mudar, o derivado recalcula. Equivalente a useMemo mas global — qualquer componente pode ler o derivado sem recalcular.
Q.Jotai funciona com SSR/Next.js?▾
A.Sim, com Provider e useHydrateAtoms para inicializar atoms com dados do servidor: `useHydrateAtoms([[userAtom, serverUser]])`. Sem Provider, atoms são globais (singleton) — problemático em SSR onde múltiplas requests compartilhariam estado. Com Provider por request, cada request tem seu próprio scope.
Termos relacionados
71/122← →