Sunday面试指南

React Context、Redux 和 Zustand 怎么选?全局状态越多越好吗?

🧑‍💻 面试官:Context、Redux 和 Zustand 怎么选?

🙋‍♂️ 我:小项目用 Context,大项目用 Redux,想简单一点用 Zustand。

🧑‍💻 面试官:一个大项目里只是切换主题,也必须上 Redux 吗?

🙋‍♂️ 我:那主题可以放 Context,复杂状态再用状态库。

🧑‍💻 面试官:复杂指什么?你怎么判断一个输入框的内容是否应该进入全局 store?

先确定状态归谁、谁要订阅、怎样更新,再选工具;项目大小不是完整的选型依据。

面试速答(60 秒版)

我会先区分局部交互状态、跨组件共享的客户端状态,以及服务端数据。只在一个表单里使用的输入,通常没必要放到全局 store。

Context 适合沿组件树提供主题、依赖或适当范围的共享值,但 Provider 值变化会影响读取它的消费者,需要注意数据拆分与更新频率。

Redux Toolkit 更适合需要明确更新流程、团队约定和调试追踪的共享状态;Zustand 的 store 与 selector 相对轻量,适合以较少结构组织共享数据。两者都要设计订阅粒度和生命周期,服务端缓存也应另按同步需求处理,而不是把所有东西都叫全局状态。

状态先按局部、共享和服务端数据区分,再选择合适的管理工具

知识点详解:全局状态的第一道题,其实是该不该全局

先问这个状态离开组件后还需要吗?

假设一个管理页面有主题、多个组件共用的筛选条件、弹窗是否打开,以及从接口获得的用户列表。

主题适合在较稳定的范围共享;筛选条件可以放在共同祖先、URL 或 store,取决于是否需要分享和跨页面保留;弹窗开关若只有局部使用,留在组件附近就好。

用户列表是服务端数据,还涉及缓存、失效、重新请求和并发。把它放进 store 并不自动解决这些问题,可以使用合适的服务端数据工具。状态能放进全局,不等于应该放进全局。

Context 是传递渠道,不是自动的精细订阅器

Context 让较深的消费者拿到 Provider 的值,避免逐层转传 props。主题、语言和依赖对象是常见用途,但它并不限于只能存这些。

问题常出在一个 Provider 里装了很多高频变化的数据。某一部分变化,会让读取这个 Context 的组件响应相应更新。把所有字段包在每轮新建的对象里,也可能增加不必要变化。

可以缩小 Provider 范围、拆分 Context、让数据与更新入口分开,或把高频共享数据交给支持适当 selector 的 store。memo 不是 Context 更新的万能挡板。

比较 Redux 和 Zustand,要看团队要管理什么

Redux 通过 action 与 reducer 等机制组织更新。现代官方推荐 Redux Toolkit,它减少旧式手写样板,并提供更明确的组织方式;不要拿十年前的繁琐示例代表今天的唯一用法。

如果团队希望更新事件可追踪、状态规范统一、复杂流程容易测试,这种约束可能有价值。成本是需要理解相应的数据流与约定。

Zustand 可以用较轻量的 store 组织共享状态,通过 selector 读取所需部分。但“轻量”不意味着可以随意混放所有模块。动作边界、错误处理、测试和服务器渲染时的隔离,仍然需要设计。

两者都能处理相当大的应用,也都能被用坏。这里比较真实 React 生态工具,不给它们编造 Python 同名库。

订阅粒度和生命周期,比换库更值得先检查

假设头部只需要登录用户的名字,却订阅整个 store。别处一个列表变化也可能影响它。先选择真正需要的值,再决定是否有必要缓存派生结果。

Zustand v5 中,返回新对象等不稳定引用的 selector 还要注意稳定输出要求;可使用各自字段 selector,或在适合的浅比较场景中使用 useShallow。不能照搬旧版的比较参数写法。

服务端渲染也要避免把每个请求的用户状态放进一个跨请求共享的全局实例。客户端持久化时还要设计迁移和退出登录的清理。

验证可以改一个无关字段,看哪些组件更新;再测试重进页面、退出登录和并发请求。这些证据比“我们项目很大,所以选 Redux”更能说明判断。

本题机制参考:React:Managing State、Redux:官方推荐 Toolkit、Zustand:useShallow。

订阅整个 store 与选择所需字段会产生不同的更新影响范围

面试官继续追问

Context 不能做状态管理吗?

可以搭配 state 或 reducer 管理合适范围的状态,但传递渠道、状态更新和精细订阅是不同能力,需要明确自己的实现。

Redux 中所有数据必须全局吗?

不需要。组件局部状态仍可留在组件,服务端数据也可按缓存需求单独处理。

有 selector 就完全不重渲染了吗?

不是。要看选择结果如何比较、引用是否稳定,以及组件自己的状态和其他依赖。订阅越精细也不等于完全没有计算成本。

面试速记卡

  • 先分类:局部交互、共享客户端状态、服务端数据。
  • Context:沿树提供值,注意范围与值变化。
  • Redux Toolkit:用明确更新流程与工具管理共享状态。
  • Zustand:轻量 store 与 selector,仍需边界和稳定输出。
  • 判断:看订阅、生命周期和调试需求,不只看项目大小。

公司面试真题

这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历