React Context vs Zustand:该如何选择?
开发者在处理 React 状态时经常犯一个错误:他们错误地使用了 Context,然后将性能问题归咎于 Context。
问题通常在于使用了单个庞大的 context 对象。当该对象中的某个值发生变化时,所有使用该 context 的组件都会重新渲染。即使某个组件只需要其中一小部分数据,它仍然会对该对象中的每一次变化做出响应。
如果你的通知每 30 秒更新一次,那么即使 Navbar 只关心用户名,它也会重新渲染。这会严重影响性能。
你无需使用库就可以解决这个问题。根据数据的变化频率来拆分你的 context。
不要使用一个巨大的 context,而是使用多个: • UserContext 用于用户数据 • UIContext 用于侧边栏状态 • NotificationContext 用于通知/警报
现在,只有当用户数据发生变化时,你的 Navbar 才会重新渲染。这种简单的拆分可以解决大部分关于性能的抱怨。
对于稳定的值,请使用 React Context: • 主题 (Themes) • 身份验证状态 (Auth status) • 语言设置 (Language settings)
Context 与 Server Components 配合得很好。而 Zustand 仅在客户端工作。
当你需要“选择性订阅”时,请使用 Zustand。Zustand 允许组件订阅状态的特定切片 (slices)。如果 store 中的某一部分发生了变化,只有监听该特定部分的组件才会重新渲染。
对于新的状态管理,请遵循以下逻辑:
如果满足以下条件,请使用 React Context: • 数据是稳定的(主题、身份验证、语言区域)。 • 你需要它支持 SSR 或 Server Components。 • 你想通过拆分 context 来避免属性钻取 (prop drilling)。
如果满足以下条件,请使用 Zustand: • 数据变化频繁。 • 组件需要监听状态的特定切片。 • 你的逻辑很复杂。
等等。不要将两者都用于 API 数据。如果你正在从服务器获取数据,请使用 TanStack Query。Context 和 Zustand 并不处理缓存或后台重新获取 (refetching)。
总结: • 一个庞大的 context 对象会导致重新渲染。请将其拆分。 • 对稳定的值使用 Zustand 是大材小用。 • 对频繁变化的数据使用 Context 会导致卡顿。 • 使用 Zustand 来处理服务器状态是选错了工具。
