Global Store Is a Shared Dependency — Why Scoped State Ownership Wins

Global Store Is a Shared Dependency — Why Scoped State Ownership Wins

全局 Store 是一种共享依赖——为什么“作用域状态所有权”才是赢家

Redux popularized the idea of a single global store — one tree of state, one set of reducers, one source of truth. It works well with one team and ten slices. It breaks down with five teams and fifty. The global store isn’t just where your state lives — it’s a shared dependency that every feature, every team, and every pull request must coordinate around. SDuX Vault™ eliminates that coordination cost by scoping state to independent FeatureCells™.

Redux 普及了单一全局 Store 的理念——一个状态树、一套 Reducer、一个事实来源。这在只有一个团队和十个切片(slice)的情况下运行良好,但在五个团队和五十个切片时就会崩溃。全局 Store 不仅仅是存放状态的地方,它还是一个共享依赖,每个功能、每个团队和每个 Pull Request 都必须围绕它进行协调。SDuX Vault™ 通过将状态限定在独立的 FeatureCells™ 中,消除了这种协调成本。

The Single Store Assumption

单一 Store 的假设

Redux centralizes state through a global store and reducer tree. Every feature adds slices to the same root object. Every selector projects from the same tree. Every action broadcasts to every reducer. At small scale, this is manageable. One developer understands the full tree. Renames are safe because the blast radius is visible. Selectors compose predictably because nobody else is changing the shape under you.

Redux 通过全局 Store 和 Reducer 树集中管理状态。每个功能都将切片添加到同一个根对象中,每个选择器(selector)都从同一棵树中进行投影,每个 Action 都会广播给所有的 Reducer。在小规模项目中,这是可控的:一名开发者就能理解整棵树;重命名很安全,因为影响范围是可见的;选择器的组合也是可预测的,因为没有其他人会在你背后改变数据结构。

At team scale, the single store becomes a shared mutable dependency — not in the Redux sense of mutable state, but in the organizational sense. Every team’s code touches the same tree. Every refactor requires cross-team awareness. Every selector is one shape change away from a silent regression.

在团队规模下,单一 Store 变成了一种共享的可变依赖——这并非指 Redux 意义上的可变状态,而是指组织层面的依赖。每个团队的代码都会触及同一棵树,每次重构都需要跨团队沟通,任何一个选择器都可能因为数据结构的改变而导致静默回归(silent regression)。

Why Global State Becomes a Liability

为什么全局状态会成为负担

The problems are structural, not conceptual. Redux’s ideas about immutability, pure functions, and predictable state transitions are sound. What breaks is the organizational model.

这些问题是结构性的,而非概念性的。Redux 关于不可变性、纯函数和可预测状态转换的理念是合理的,但其组织模型却行不通。

  • Shape coupling: Selectors depend on the global tree structure. When Team A renames a property in their slice, Team B’s selector that composes across slices breaks silently.
  • 数据结构耦合: 选择器依赖于全局树结构。当 A 团队重命名其切片中的属性时,B 团队跨切片组合的选择器就会静默失效。
  • Action namespace collisions: Two teams define RESET action types. Both reducers respond. Neither team realizes the collision until production.
  • Action 命名空间冲突: 两个团队都定义了 RESET 类型的 Action,导致两个 Reducer 同时响应。直到上线生产环境前,双方都不会意识到这种冲突。
  • Middleware interference: Team A adds logging middleware. Team B adds analytics middleware. Both intercept the same actions. Registration order determines behavior — and nobody documents what the correct order is.
  • 中间件干扰: A 团队添加了日志中间件,B 团队添加了分析中间件,两者都会拦截相同的 Action。注册顺序决定了行为,但没人记录正确的顺序是什么。
  • Merge conflict magnets: The root reducer file, the root state interface, and the barrel export index are touched by every feature branch. They become the most contested files in the repository.
  • 合并冲突磁铁: 根 Reducer 文件、根状态接口和 Barrel 导出索引文件会被每个功能分支触及,它们成为了仓库中最容易产生冲突的文件。

None of these problems are bugs in Redux. They are consequences of putting every feature’s state in one shared structure. The global store doesn’t scale with teams — it scales with discipline. And discipline doesn’t survive deadline pressure.

这些问题都不是 Redux 的 Bug,而是将所有功能的状态放入一个共享结构中的后果。全局 Store 无法随团队规模扩展,它依赖于纪律,而纪律在截止日期的压力下往往无法维持。

Scoped Ownership with FeatureCells

使用 FeatureCells 实现作用域所有权

In SDuX Vault, state is owned by independent FeatureCells. Each cell encapsulates its own typed state, its own pipeline, and its own lifecycle boundary. No other cell can read or write another cell’s state directly.

在 SDuX Vault 中,状态由独立的 FeatureCells 拥有。每个 Cell 封装了其自身的类型化状态、流水线和生命周期边界。其他 Cell 无法直接读取或写入另一个 Cell 的状态。

import { Vault, FeatureCell } from '@sdux-vault/core';
Vault({ devMode: true, logLevel: 'off' });

// Team A owns cart state
export const cartCell = FeatureCell({ key: 'cart', initialState: { items: [], total: 0 } });

// Team B owns user profile state
export const userProfileCell = FeatureCell({ key: 'user-profile', initialState: { name: '', preferences: {} } });

// Team C owns notifications state
export const notificationsCell = FeatureCell({ key: 'notifications', initialState: { items: [], unreadCount: 0 } });

Three teams. Three cells. Zero shared state. Team A can rename every property in the cart state shape without Team B or Team C knowing or caring. There is no root reducer file. There is no global state interface. There is no barrel export that every branch touches.

三个团队,三个 Cell,零共享状态。A 团队可以重命名购物车状态结构中的任何属性,而 B 团队或 C 团队无需知晓也不必关心。没有根 Reducer 文件,没有全局状态接口,也没有每个分支都会触及的 Barrel 导出文件。

Key takeaway: Each FeatureCell is identified by a unique key and may be registered exactly once. No other cell can access its state directly — isolation is enforced by architecture, not by team agreement.

核心要点: 每个 FeatureCell 都由唯一的 Key 标识,且只能注册一次。其他 Cell 无法直接访问其状态——隔离性是由架构强制执行的,而不是靠团队协议。

What Changes for Your Team

对你的团队意味着什么

The organizational impact is immediate. When state ownership is scoped to cells, team boundaries align with state boundaries.

组织层面的影响是立竿见影的。当状态所有权被限定在 Cell 中时,团队边界就与状态边界对齐了。

Global StoreFeatureCell Ownership
Every team touches the root state interfaceEach team owns only its cell’s type
Selector changes require cross-team reviewState access is scoped to the owning cell
Action namespace collisions are possibleNo actions — updates target the owner directly
Root reducer file is a merge conflict magnetNo root reducer — cells are registered independently
Middleware affects all statePipeline behaviors are scoped per cell
Feature removal requires tree surgeryRemove the cell registration — done
全局 StoreFeatureCell 所有权
每个团队都触及根状态接口每个团队只拥有其 Cell 的类型
选择器变更需要跨团队评审状态访问仅限于所属 Cell
可能发生 Action 命名空间冲突无 Action——更新直接指向所有者
根 Reducer 文件是合并冲突磁铁无根 Reducer——Cell 独立注册
中间件影响所有状态流水线行为限定在每个 Cell 内
功能移除需要“外科手术”式修改移除 Cell 注册即可——完成

This isn’t just a technical improvement — it’s an organizational one. Teams stop coordinating around shared files. Pull requests shrink because they only touch the code their feature owns. Refactors become safe because the blast radius is bounded by the cell boundary.

这不仅是技术上的改进,更是组织上的改进。团队不再需要围绕共享文件进行协调。Pull Request 变小了,因为它们只触及自己功能拥有的代码。重构变得安全,因为影响范围被限制在 Cell 边界内。

Key takeaway: Redux scopes state by convention (slice naming, selector discipline, action prefixing). SDuX Vault scopes state by architecture — the cell boundary is enforced, not agreed upon.

核心要点: Redux 通过约定(切片命名、选择器规范、Action 前缀)来限定状态作用域。SDuX Vault 通过架构来限定状态作用域——Cell 边界是强制执行的,而非仅仅依靠口头协议。

Try It Yourself

亲自尝试

Read the full Redux Concepts in SDuX Vault page for a section-by-section mapping of State, Actions, Dispatch, Reducers, Effects, Selectors, and Testing. Explore the FeatureCell API documentation to see the full registration surface, or jump into a live StackBlitz demo to create your own isolated cells with typed state and scoped ownership.

阅读完整的 SDuX Vault 中的 Redux 概念 页面,查看关于状态、Action、Dispatch、Reducer、Effect、选择器和测试的逐节映射。浏览 FeatureCell API 文档以查看完整的注册接口,或者直接进入 StackBlitz 在线演示,创建你自己的、带有类型化状态和作用域所有权的隔离 Cell。