npx skills add https://github.com/s-hiraoku/skills-factory --skill jotai-expertJotai 是一个基于原子化理念、原始且灵活的 React 状态管理库。请始终参考 https://jotai.org/ 以获取最新的 API 详情。
Need state management?
├── Simple local state → useState (no Jotai needed)
├── Shared state across components
│ ├── Few components, same tree → Context may suffice
│ └── Many components, complex → Use Jotai ✓
└── Global app state → Use Jotai ✓
Choosing atom type:
├── Static value → atom(initialValue)
├── Computed from other atoms → atom((get) => ...)
├── Need to modify other atoms → atom(null, (get, set) => ...)
├── Persist to storage → atomWithStorage()
├── List of items → splitAtom() or atoms-in-atom
└── Parameterized data → atomFamily()
Performance issue?
├── Component re-renders too often
│ ├── Only reading? → useAtomValue
│ ├── Only writing? → useSetAtom
│ ├── Large object? → selectAtom / focusAtom
│ └── List items? → splitAtom
└── Async loading states → loadable() or manual loading atoms
import { atom } from 'jotai'
// 1. Primitive: holds value
const countAtom = atom(0)
// 2. Derived read-only: computed from others
const doubleAtom = atom((get) => get(countAtom) * 2)
// 3. Derived read-write: custom setter
const celsiusAtom = atom(0)
const fahrenheitAtom = atom(
(get) => get(celsiusAtom) * 9/5 + 32,
(get, set, newF: number) => set(celsiusAtom, (newF - 32) * 5/9)
)
// 4. Write-only (action): no read value
const incrementAtom = atom(null, (get, set) => {
set(countAtom, get(countAtom) + 1)
})
Jotai is a primitive and flexible state management library for React using an atomic approach. Always reference https://jotai.org/ for the latest API details.
Need state management?
├── Simple local state → useState (no Jotai needed)
├── Shared state across components
│ ├── Few components, same tree → Context may suffice
│ └── Many components, complex → Use Jotai ✓
└── Global app state → Use Jotai ✓
Choosing atom type:
├── Static value → atom(initialValue)
├── Computed from other atoms → atom((get) => ...)
├── Need to modify other atoms → atom(null, (get, set) => ...)
├── Persist to storage → atomWithStorage()
├── List of items → splitAtom() or atoms-in-atom
└── Parameterized data → atomFamily()
Performance issue?
├── Component re-renders too often
│ ├── Only reading? → useAtomValue
│ ├── Only writing? → useSetAtom
│ ├── Large object? → selectAtom / focusAtom
│ └── List items? → splitAtom
└── Async loading states → loadable() or manual loading atoms
import { atom } from 'jotai'
// 1. Primitive: holds value
const countAtom = atom(0)
// 2. Derived read-only: computed from others
const doubleAtom = atom((get) => get(countAtom) * 2)
// 3. Derived read-write: custom setter
const celsiusAtom = atom(0)
const fahrenheitAtom = atom(
(get) => get(celsiusAtom) * 9/5 + 32,
(get, set, newF: number) => set(celsiusAtom, (newF - 32) * 5/9)
)
// 4. Write-only (action): no read value
const incrementAtom = atom(null, (get, set) => {
set(countAtom, get(countAtom) + 1)
})
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 需求 | Hook | 变化时重新渲染 |
|---|---|---|
| 仅读取 | useAtomValue(atom) | 是 |
| 仅写入 | useSetAtom(atom) | 否 |
| 两者都要 | useAtom(atom) | 是 |
// ❌ WRONG: Creates new atom every render
function Component() {
const myAtom = atom(0) // Unstable reference
}
// ✅ CORRECT: Define outside component
const myAtom = atom(0)
function Component() {
const [value] = useAtom(myAtom)
}
// ✅ CORRECT: useMemo for dynamic atoms
function Component({ id }) {
const itemAtom = useMemo(() => atom(items[id]), [id])
}
// ❌ BAD: Re-renders on any user field change
function UserProfile() {
const [user] = useAtom(userAtom)
return <h1>{user.name}</h1>
}
// ✅ GOOD: Only re-renders when name changes
import { selectAtom } from 'jotai/utils'
const nameAtom = selectAtom(userAtom, (u) => u.name)
function UserName() {
const name = useAtomValue(nameAtom)
return <h1>{name}</h1>
}
import { splitAtom } from 'jotai/utils'
const todosAtom = atom<Todo[]>([])
const todoAtomsAtom = splitAtom(todosAtom, (t) => t.id)
function TodoList() {
const [todoAtoms] = useAtom(todoAtomsAtom)
return todoAtoms.map((todoAtom) => (
<TodoItem key={todoAtom.toString()} atom={todoAtom} />
))
}
// Each item updates independently
function TodoItem({ atom }) {
const [todo, setTodo] = useAtom(atom)
// Changes here don't re-render other items
}
import { focusAtom } from 'jotai-optics'
const formAtom = atom({ name: '', email: '', address: { city: '' } })
// Focused atoms for each field
const nameAtom = focusAtom(formAtom, (o) => o.prop('name'))
const cityAtom = focusAtom(formAtom, (o) => o.prop('address').prop('city'))
// Each field component only re-renders when its value changes
import { loadable } from 'jotai/utils'
const asyncDataAtom = atom(async () => fetch('/api').then(r => r.json()))
const loadableDataAtom = loadable(asyncDataAtom)
function Component() {
const data = useAtomValue(loadableDataAtom)
if (data.state === 'loading') return <Spinner />
if (data.state === 'hasError') return <Error />
return <Data value={data.data} />
}
按主题组织的详细文档:
在实现或审查 Jotai 代码时,请加载相关的参考文件以获取详细指导。
每周安装量
95
代码仓库
首次出现
2026年1月28日
安全审计
安装于
opencode79
codex77
cursor74
gemini-cli60
github-copilot59
amp56
| Need | Hook | Re-renders on change |
|---|---|---|
| Read only | useAtomValue(atom) | Yes |
| Write only | useSetAtom(atom) | No |
| Both | useAtom(atom) | Yes |
// ❌ WRONG: Creates new atom every render
function Component() {
const myAtom = atom(0) // Unstable reference
}
// ✅ CORRECT: Define outside component
const myAtom = atom(0)
function Component() {
const [value] = useAtom(myAtom)
}
// ✅ CORRECT: useMemo for dynamic atoms
function Component({ id }) {
const itemAtom = useMemo(() => atom(items[id]), [id])
}
// ❌ BAD: Re-renders on any user field change
function UserProfile() {
const [user] = useAtom(userAtom)
return <h1>{user.name}</h1>
}
// ✅ GOOD: Only re-renders when name changes
import { selectAtom } from 'jotai/utils'
const nameAtom = selectAtom(userAtom, (u) => u.name)
function UserName() {
const name = useAtomValue(nameAtom)
return <h1>{name}</h1>
}
import { splitAtom } from 'jotai/utils'
const todosAtom = atom<Todo[]>([])
const todoAtomsAtom = splitAtom(todosAtom, (t) => t.id)
function TodoList() {
const [todoAtoms] = useAtom(todoAtomsAtom)
return todoAtoms.map((todoAtom) => (
<TodoItem key={todoAtom.toString()} atom={todoAtom} />
))
}
// Each item updates independently
function TodoItem({ atom }) {
const [todo, setTodo] = useAtom(atom)
// Changes here don't re-render other items
}
import { focusAtom } from 'jotai-optics'
const formAtom = atom({ name: '', email: '', address: { city: '' } })
// Focused atoms for each field
const nameAtom = focusAtom(formAtom, (o) => o.prop('name'))
const cityAtom = focusAtom(formAtom, (o) => o.prop('address').prop('city'))
// Each field component only re-renders when its value changes
import { loadable } from 'jotai/utils'
const asyncDataAtom = atom(async () => fetch('/api').then(r => r.json()))
const loadableDataAtom = loadable(asyncDataAtom)
function Component() {
const data = useAtomValue(loadableDataAtom)
if (data.state === 'loading') return <Spinner />
if (data.state === 'hasError') return <Error />
return <Data value={data.data} />
}
Detailed documentation organized by topic:
When implementing or reviewing Jotai code, load the relevant reference file for detailed guidance.
Weekly Installs
95
Repository
First Seen
Jan 28, 2026
Security Audits
Installed on
opencode79
codex77
cursor74
gemini-cli60
github-copilot59
amp56
GSAP 框架集成指南:Vue、Svelte 等框架中 GSAP 动画最佳实践
3,200 周安装
Webpack 5 打包配置指南:优化代码分割、Tree Shaking 与构建性能
163 周安装
iOS/macOS 构建调试指南:解决 Xcode SPM/CocoaPods 依赖项与编译错误
163 周安装
AVFoundation 相机问题诊断指南:解决 iOS 相机预览冻结、旋转错误、捕获缓慢
164 周安装
Sentry 错误追踪指南:Node.js/Python 异常监控、性能分析与最佳实践
162 周安装
iOS TestFlight崩溃调查指南:使用Xcode Organizer快速定位与修复Beta测试问题
162 周安装
iOS小组件与扩展开发指南:解决数据更新、实时活动与控制中心问题
161 周安装