打开网易新闻 查看精彩图片

2018年的某个周一,意大利团队Fattutto的代码库出现了8层嵌套的Provider。这不是技术债务,是架构设计从一开始就没想明白一个问题:状态到底该放哪儿?

前端开发者入行时都会遇到一个隐形选择题。框架默认把状态塞进组件,全局状态成了需要额外付费的VIP服务。但作者Dylan的Inglorious Web系列提出了一个反直觉观点:状态本该全局,除非你主动隔离它

项目一:8层Provider的"俄罗斯套娃"

项目一:8层Provider的"俄罗斯套娃"

Fattutto是个发票应用,团队4个人,开发周期2个月。2018年的Redux还没有RTK(Redux Toolkit),纯Redux写起来像在做文书工作。Context API看起来是个轻量选择。

Context的问题不是不能做全局状态,是性能陷阱。只要context的值变了,所有消费者都会重渲染。唯一的解药是把context切得尽可能细。

功能越加越多,每个需要共享的新需求都变成一个新的Provider。等应用成熟,根组件变成了这样:Theme套User,User套Licence,Licence套IdsToRemove……一共8层。

接手团队后来重构减少了层数。这证明Context足够灵活,可以补救。但"先污染后治理"的模式,本身就是架构设计的上限。

项目二:工厂HMI的4年长征

项目二:工厂HMI的4年长征

打开网易新闻 查看精彩图片

2020年,Dylan加入Tetra Pak做工业HMI(人机界面),给工厂控制系统做界面。这个项目持续了4年。

他带着Fattutto的教训进场:哪怕初期状态看起来很小,第一天就上RTK。这次没有Provider套娃的问题,但遇到了新麻烦。

工业HMI的状态规模是消费级应用的10倍起步。每个传感器、每台机器、每个报警都有状态。RTK的boilerplate(样板代码)在规模面前开始咬人。一个slice文件动辄几百行,团队花了大量时间写重复的模式。

全局状态的选择是对的,但工具选得不够锋利。4年项目中期,他们开始用代码生成工具批量生产slice。这不是技术失败,是工具链和规模不匹配的典型症状。

项目三:3个月项目的"局部状态幻觉"

项目三:3个月项目的"局部状态幻觉"

2023年,Dylan接了个短期咨询项目。客户说"就是个简单后台,局部状态够了"。

他坚持了全局优先的原则。3个月后项目交付时,客户提了两个"小改动":加一个跨页面的筛选状态,加一个需要持久化的用户偏好。团队用2小时改完,没有重构,没有技术债务。

同期另一个类似项目用了局部状态优先。同样的"小改动",团队花了2周做状态提升(lifting state up),重构了7个组件,引入了新的context。

打开网易新闻 查看精彩图片

局部状态的本质是延迟决策。你今天省下的架构思考,会变成明天的重构账单,带利息。

为什么框架默认是反的

为什么框架默认是反的

React、Vue、Angular都把局部状态设为默认。这不是技术原因,是教学原因。

新手教程需要"Hello World"能跑起来。全局状态需要理解数据流、副作用、持久化,认知门槛高。框架选择先让你跑起来,再让你还债。

但企业级项目的代价是真实的。Dylan的3个项目覆盖了消费应用、工业系统、短期后台,共同点是:状态边界永远比你想象的更容易被打破

Context API的Provider套娃、Redux的样板代码爆炸、局部状态的后期重构——这三种痛,本质上都是同一个错误在不同阶段的临床表现。

Inglorious Web的做法是:全局状态作为基础设施,用显式隔离替代隐式局部。不是"需要全局时再提取",是"默认全局,需要隔离时再圈地"。

这个思路的代价是前期设计成本。收益是后期改动成本趋近于零。对于生命周期超过6个月的项目,这笔账很容易算过来。

Dylan在系列文章里埋了一个细节:Fattutto的8层Provider截图,他保留了7年。每次有人跟他说"这个项目很简单,局部状态够了",他就把这张图发过去。