composable-architecture

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

The Composable Architecture (TCA)

可组合架构(TCA)

TCA provides architecture for building complex, testable features through composable reducers, centralized state management, and side effect handling. The core principle: predictable state evolution with clear dependencies and testable effects.
TCA 通过可组合的reducer、集中式状态管理和副作用处理,为构建复杂、可测试的功能提供架构支持。核心原则:通过清晰的依赖关系和可测试的副作用实现可预测的状态演变。

Reference Loading Guide

参考资料加载指南

ALWAYS load reference files if there is even a small chance the content may be required. It's better to have the context than to miss a pattern or make a mistake.
ReferenceLoad When
Reducer StructureCreating new reducers, setting up
@Reducer
,
State
,
Action
, or
@ViewAction
Views - BindingUsing
@Bindable
, two-way bindings,
store.send()
, or
.onAppear
/
.task
Views - CompositionUsing
ForEach
with stores, scoping to child features, or optional children
Navigation - BasicsSetting up
NavigationStack
, path reducers, pushing/popping, or programmatic dismiss
Navigation - AdvancedDeep linking, recursive navigation, or combining NavigationStack with sheets
Shared StateUsing
@Shared
,
.appStorage
,
.withLock
, or sharing state between features
DependenciesCreating
@DependencyClient
, using
@Dependency
, or setting up test dependencies
EffectsUsing
.run
,
.send
,
.merge
, timers, effect cancellation, or async work
PresentationUsing
@Presents
,
AlertState
, sheets, popovers, or the Destination pattern
Testing - FundamentalsSetting up test suites,
makeStore
helpers, or understanding Equatable requirements
Testing - PatternsTesting actions, state changes, dependencies, errors, or presentations
Testing - AdvancedUsing
TestClock
, keypath matching,
exhaustivity = .off
, or time-based tests
Testing - UtilitiesTest data factories,
LockIsolated
,
ConfirmationDialogState
testing, or
@Shared
testing
PerformanceOptimizing state updates, high-frequency actions, memory, or store scoping
只要有一丝可能需要用到相关内容,就一定要加载参考文件。 拥有上下文总比遗漏模式或犯错要好。
参考资料加载时机
Reducer结构创建新reducer、配置
@Reducer
State
Action
@ViewAction
视图 - 绑定使用
@Bindable
、双向绑定、
store.send()
.onAppear
/
.task
视图 - 组合
ForEach
与stores结合使用、限定到子功能范围或处理可选子项时
导航 - 基础配置
NavigationStack
、路径reducer、页面推入/弹出或程序化关闭时
导航 - 进阶实现深度链接、递归导航或结合NavigationStack与弹窗时
共享状态使用
@Shared
.appStorage
.withLock
或在功能间共享状态时
依赖管理创建
@DependencyClient
、使用
@Dependency
或配置测试依赖时
副作用处理使用
.run
.send
.merge
、定时器、副作用取消或异步任务时
视图展示使用
@Presents
AlertState
、弹窗、弹出框或Destination模式时
测试 - 基础配置测试套件、使用
makeStore
辅助工具或理解Equatable要求时
测试 - 模式测试动作、状态变化、依赖、错误或视图展示时
测试 - 进阶使用
TestClock
、键路径匹配、
exhaustivity = .off
或基于时间的测试时
测试 - 工具使用测试数据工厂、
LockIsolated
、测试
ConfirmationDialogState
或测试
@Shared
性能优化优化状态更新、高频动作、内存或store范围时

Common Mistakes

常见错误

  1. Over-modularizing features — Breaking features into too many small reducers makes state management harder and adds composition overhead. Keep related state and actions together unless there's genuine reuse.
  2. Mismanaging effect lifetimes — Forgetting to cancel effects when state changes leads to stale data, duplicate requests, or race conditions. Use
    .concatenate
    for sequential effects and
    .cancel
    when appropriate.
  3. Navigation state in wrong places — Putting navigation state in child reducers instead of parent causes unnecessary view reloads and state inconsistencies. Navigation state belongs in the feature that owns the navigation structure.
  4. Testing without TestStore exhaustivity — Skipping TestStore assertions for "simple" effects or "obvious" state changes means you miss bugs. Use exhaustivity checking religiously; it catches regressions early.
  5. Mixing async/await with Effects incorrectly — Converting async/await to
    .run
    effects without proper cancellation or error handling loses isolation guarantees. Wrap async operations carefully in
    .run
    with
    yield
    statements.
  1. 过度模块化功能 — 将功能拆分为过多小型reducer会增加状态管理难度和组合开销。除非确实需要复用,否则应将相关状态和动作放在一起。
  2. 副作用生命周期管理不当 — 状态变化时忘记取消副作用会导致数据过期、重复请求或竞态条件。对于顺序执行的副作用使用
    .concatenate
    ,并在合适的时机使用
    .cancel
  3. 导航状态存放位置错误 — 将导航状态放在子reducer而非父reducer中会导致不必要的视图重载和状态不一致。导航状态应属于拥有导航结构的功能模块。
  4. 测试时未启用TestStore穷尽检查 — 跳过对“简单”副作用或“明显”状态变化的TestStore断言会导致遗漏bug。务必严格使用穷尽检查,它能尽早发现回归问题。
  5. 错误混用async/await与Effects — 在未进行适当取消或错误处理的情况下将async/await转换为
    .run
    副作用会失去隔离保障。请使用
    yield
    语句小心地将异步操作包裹在
    .run
    中。