React中的状态管理:Zustand和Jotai

1526
4 分钟阅读
React中的状态管理:Zustand和Jotai
"AI摘要: 本文探讨了在React应用中进行状态管理的不同方法,重点介绍了Zustand和Jotai两种全局状态管理工具。文章首先分析了使用useState和useContext进行状态管理的局限性,包括性能问题和复杂的组件更新逻辑。接着,详细介绍了Zustand的集中式状态管理模式及其优势,如细粒度的状态更新控制。然后,讨论了Jotai的分布式原子(Atom)模型及其在提高渲染性能方面的优势。最后,作者建议在大型应用中使用Zustand或Jotai来简化状态管理代码,提高效率。"

刚刚又在鞭策Gemini 3干活,改造另外一个前端UI设计为卖点的产品,看能不能改造成我自己的产品,然后推广出去。

在Gemini 3干活的空袭,发现项目中使用Zustand作为状态管理,虽然我一直一把梭哈useState进行状态管理,有的时候也用Jotai,但是对于这些高级的状态管理工具,一直没有深入研究研究。

react中的状态

我们知道UI的渲染大致可以分为:状态 + 计算逻辑 + 渲染逻辑。而react中建议通过hooks把状态和计算逻辑统一管理,也就是useState之类的函数,从而实现与UI渲染的html,css逻辑分离。

有的时候,我们需要更加复杂的状态共享情况,比如在登录了之后,不同组件都需要因为登录状态的改变而改变。由于useState是局部状态,随着组件挂载/卸载而自生自灭,因此,我们需要进行状态提升:

  1. 提升到父组件:这样兄弟组件之间就能共享状态
  2. 提升到全局:通过useContext实现更广的,更全局的状态共享

但是这样又引入了性能问题:只要一个状态改变了,全部依赖的组件都需要重新渲染

所以,我们又需要进行细粒度的管理,在useState和useContext中写一堆判断逻辑,如果是组件中含有该状态,才进行更新,造成了不小的心智负担。

Zustand

既然全局状态管理非常有必要,但是细粒度的组件更新管理也需要设计,不如用Zustand组件吧。

Zustand是一个全局 + 集中式的状态管理工具,react全局共享一个巨大的useState(粗糙地可以这么理解),在react中就是这样:

// 假设这是一个“用户/设置”Store
const useUserStore = create(() => ({
  userName: 'Alice',
  theme: 'dark',
  notifications: [],
  // ...所有东西都在这里
}));

一个巨大的, 全局的store,状态和操作逻辑都被封装在了这里面

当某个小组件需要使用其中一个状态的时候,可以写:

const count = useKitchenStore(state => state.counter); // 我只要“计数器”这个食材

这样即使useKitchenStore中其他的状态发生了修改,也不会导致依赖counter这个状态的组件的重新渲染。

由于Zustand是一个巨大的,全局的store,其可能在大型的应用中比较好用,因为所有的状态都封装在一个对象中,观察所有的状态非常方便。

Jotai

同样也是一个全局状态管理的工具,不过是偏分布式的,不会有一个巨大的对象保存全部的状态,而是分散开为多个小对象(也依然是全局的)

最小的单元为Atom,封装着最小的状态和操作逻辑

// 独立的盒子 (Atom)
const counterAtom = atom(0);
const userNameAtom = atom('Alice');
const themeAtom = atom('dark');

当需要用某个UI组件需要用到某个状态的时候,内容如下:

const [count] = useAtom(counterAtom); // 我直接拿“计数器”这个盒子

由于状态本来就分散在不同的Atom中,因此这种模型的状态管理,天然组件渲染性能很好

总结

以后少用useContext和useState,直接梭哈Jotai或者Zustand,能少写一些通用代码逻辑就少写,早点完成早下班