智能网盘直链下载解决方案:告别限速,拥抱高速下载新时代
2026/6/27 0:10:11
@[toc]
如果你做过 RN 列表,一定经历过这种阶段:
useState挺顺问题真的在 FlatList 吗?
大多数时候,在状态模型。
为了公平,我们先约定一个非常常见的场景:
function List() { const likedMap = useSelector(state => state.likedMap) return ( <FlatList data={data} renderItem={({ item }) => ( <Item item={item} liked={likedMap[item.id]} /> )} /> ) }我们不讲概念,直接讲链路:
哪怕你:
List 这一层,永远逃不掉。
状态变化是“广播式”的,而列表最怕广播。
Redux 很适合:
但它对“高频、局部、交互型状态”是天然不友好的。
我们换成 Jotai。
constlikedAtom=atom<Record<string,boolean>>({})function Item({ id }) { const [likedMap, setLikedMap] = useAtom(likedAtom) const liked = likedMap[id] return ( <Pressable onPress={() => setLikedMap(prev => ({ ...prev, [id]: !prev[id] })) } > <Text>{liked ? '❤️' : '🤍'}</Text> </Pressable> ) }为什么?
因为:
Jotai 没有魔法,它只是更细粒度。
关键在这一步:
constlikedAtomFamily=atomFamily((id:string)=>atom(false))function Item({ id }) { const [liked, setLiked] = useAtom(likedAtomFamily(id)) return ( <Pressable onPress={() => setLiked(v => !v)}> <Text>{liked ? '❤️' : '🤍'}</Text> </Pressable> ) }现在变化的是:
这时 Jotai 的优势才真正出现。
Zustand 是 RN 圈里这两年非常受欢迎的状态库。
constuseStore=create(set=>({likedMap:{},toggleLike:(id)=>set(state=>({likedMap:{...state.likedMap,[id]:!state.likedMap[id],},})),}))function Item({ id }) { const liked = useStore( state => state.likedMap[id] ) const toggleLike = useStore( state => state.toggleLike ) return ( <Pressable onPress={() => toggleLike(id)}> <Text>{liked ? '❤️' : '🤍'}</Text> </Pressable> ) }重点只有一个:
selector 是订阅边界。
likedMap[id]这点和 Redux 完全不同。
| 维度 | Redux | Jotai | Zustand |
|---|---|---|---|
| 更新模型 | 广播 | 原子订阅 | 选择器订阅 |
| 默认粒度 | 全局 | 原子 | selector |
| 列表友好度 | 低 | 中(需设计) | 高 |
| 心智成本 | 中 | 高 | 低 |
| 易踩坑指数 | 高 | 中 | 低 |
不是偶然。
RN 的渲染模型决定了:
Zustand 的 selector 模型,天然契合 RN 的这种“显式渲染”。
需要注意几个现实问题:
所以记住一句话:
Zustand 是局部状态放大器,不是全局垃圾桶。
在真实 RN 项目里,一个非常稳妥的搭配是:
这不是“多此一举”,而是按渲染成本分层。
你会发现一个很残酷的事实:
RN 不会帮你隐藏状态设计的错误。
Web 项目里还能靠浏览器苟住,
RN 会把每一次设计失误,直接变成卡顿反馈给你。
如果只记一句:
在 RN 列表里,谁能把“谁重渲”控制到最小,谁就赢了。
Redux 赢在秩序,
Jotai 赢在精细,
Zustand 赢在直觉。