如何仅用Jotai实现分页加载数据的累加状态管理
解决方案:用Jotai原子替代useState/useEffect管理分页累积数据
核心思路
把分页数据的累积逻辑完全迁移到Jotai原子体系中:
- 新增原子存储所有已加载的漫画数据
- 利用Jotai的依赖追踪特性,当新分页数据加载完成时自动追加到全局数据原子
- 组件直接读取全局数据原子,移除useState和useEffect
代码实现
1. 定义核心原子
import { atom } from 'jotai' import { loadable, atomWithEffect } from 'jotai/utils' // 你的分页原子(假设已存在) export const pagination = atom(1) // 存储所有已加载的漫画数据 export const allComicsAtom = atom<Comics[]>([]) // 异步加载指定页的漫画数据 export const fetchComicsByPageAtom = atom(async (get) => { const page = get(pagination) const res = await getMarvelData({ resource: 'comics', page }) return res.data.results as Comics[] }) // 包装为可追踪加载状态的原子 export const loadableComics = loadable(fetchComicsByPageAtom) // 副作用原子:新数据加载完成后自动追加到全局列表 export const appendComicsEffectAtom = atomWithEffect((get, set) => { const loadableState = get(loadableComics) if (loadableState.state === 'hasData') { set(allComicsAtom, prev => [...prev, ...loadableState.data]) } })
2. 简化组件代码
export function Main(): JSX.Element { // 订阅全局漫画数据和加载状态 const [allComics] = useAtom(allComicsAtom) const [loadableState] = useAtom(loadableComics) // 订阅副作用原子(触发数据追加逻辑) useAtom(appendComicsEffectAtom) useEndOfPageObserver() // 原滚动加载逻辑,负责更新pagination的page值 // 错误处理 if (loadableState.state === 'hasError') return <Error /> return ( <main className='grid gap-4 grid-cols-4'> {allComics.map((comic) => ( <ComicsCard comics={comic} key={comic.id} /> ))} {/* 加载状态提示 */} {loadableState.state === 'loading' && <Loading />} </main> ) }
关键说明
allComicsAtom:作为单一数据源,存储所有已加载的漫画数据,替代原来的useStateatomWithEffect:监听loadableComics的状态变化,当新数据加载完成时自动追加到全局列表,替代原来的useEffect- 组件只需要读取原子状态,不再需要手动处理数据累积逻辑,完全由Jotai的依赖驱动更新
内容的提问来源于stack exchange,提问作者dev.iamunhoz
相关产品推荐
相关产品推荐

