把React当银弹五年后,我劝你先想清楚状态到底该归谁管
摘要:本文反思将React视为银弹的思维,强调状态归属设计比工具选型更重要。通过分析组件状态、共享状态与服务端缓存的区别,提出前置梳理状态流向的方法,帮助团队避开常见维护陷阱。
五年前,我在团队里力排众议,把一套运行多年的服务端渲染模板系统迁移到了React。那时候的理由很充分:组件化、声明式UI、单向数据流,这些概念听起来就像是为复杂前端量身定制的解药。五年过去,项目从最初的十几个页面膨胀到两百多个路由,参与过的人换了两茬,我回头再看当年那个决定,最大的感触不是React好不好用,而是我们太容易把技术选型当成万能钥匙,却忽略了更根本的问题——状态到底该归谁管。
这个问题听起来像老生常谈,但真正在工程里把它想清楚的人并不多。React本身只负责视图层,它不关心你的数据从哪来、到哪去,也不强制你用什么方式管理状态。这种开放性既是优势也是陷阱。很多人刚接触React时,会本能地把所有数据都塞进组件状态里,用useState和useEffect拼凑出一个能跑的页面,然后随着需求迭代,状态开始四处散落:有的在组件内部,有的被提升到父级,有的通过Context共享,还有的干脆挂在全局store上。最终代码变成一张蜘蛛网,改一个字段要翻五个文件,排查一个渲染问题得把整条链路捋一遍。这时候你很难说清楚是React的问题,还是状态归属没设计好的问题。
我见过不少团队在遇到这类困境时,第一反应是引入更重的状态管理方案。从Redux到MobX,再到后来的Zustand、Jotai、Valtio,每一款都有拥趸,每一款都宣称能解决状态混乱。但工具换了一轮,混乱依旧存在,因为问题的根不在工具,而在决策逻辑。状态该归谁管,本质上是一个架构分层问题,它取决于数据的生命周期、使用范围、更新频率以及和业务逻辑的耦合程度。把这些维度想清楚,哪怕只用React自带的useState和useReducer,也能写出可维护的代码;反过来,如果缺乏判断标准,再强大的状态库也只会把混乱包装得更精致。
举个例子,表单输入这类高频变化的状态,天然适合留在组件内部,没必要上提,更没必要全局共享。而用户登录信息、主题偏好这类跨页面、跨层级的数据,才需要考虑放在更上层的位置。至于服务端拉取的列表数据,它本质上是一份缓存,应该由专门的数据请求层来管理,而不是和UI状态混在一起。很多项目之所以越写越乱,就是因为把这三类状态混为一谈,用同一套模式去处理所有场景。React的生态里从来不缺方案,缺的是对状态进行分类和划界的意识。
近两年React社区在服务端组件和流式渲染上投入了大量精力,这其实从侧面印证了一个趋势:前端框架正在试图把一部分状态管理的职责往服务端转移。这不是倒退,而是一种分工的再平衡。当数据的获取和变更逻辑能够更自然地靠近数据源时,前端就不需要承担那么多本该属于后端的职责。但这并不意味着前端状态管理会消失,而是要求开发者更精准地判断哪些状态真正属于客户端,哪些只是服务端数据的投影。这个判断能力,比熟练使用某个状态库重要得多。
我在带团队时有个习惯,新项目启动前会先画一张状态流向图,把每个关键数据标出来,注明它的来源、消费方和更新触发条件。这张图往往比技术选型文档更有价值,因为它迫使大家提前面对状态归属的问题。很多争论在画图的过程中就消解了,因为大家发现有些状态根本不需要存在,有些状态应该由后端接口直接返回,还有些状态用URL参数就能表达,连组件状态都不用占。这种前置的梳理,比事后重构省力得多。
当然,强调状态归属并不意味着否定React的价值。恰恰相反,正是React的灵活性让我们有机会去思考这些问题。如果框架强制规定了一切,开发者反而容易变成配置工人,失去对数据流的掌控感。但灵活性也意味着责任,把React当银弹的人,往往是在逃避这份责任。他们希望找到一个一劳永逸的架构,让所有状态问题自动消失,这在任何技术栈里都不现实。
五年后的今天,如果有人问我该不该用React,我的回答依然是肯定的,但我会补上一句:先想清楚你的状态到底该归谁管。这个问题没有标准答案,它取决于你的业务形态、团队规模和演进阶段。但只要你开始认真对待它,就已经避开了大多数前端项目最常见的坑。技术选型只是起点,架构判断才是长期考验。