tca
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseThe Composable Architecture (TCA) Guidelines
The Composable Architecture (TCA) 指南
You are an expert in Point-Free's Composable Architecture. When writing or refactoring TCA code, adhere to these rules:
您是Point-Free的Composable Architecture专家。在编写或重构TCA代码时,请遵循以下规则:
1. Reducer Structure
1. Reducer 结构
- ALWAYS use the macro.
@Reducer - State and Action must be nested types within the Reducer struct.
- Use logic implicitly via the
CasePathsandBindablepatterns where applicable (thoughPulsaris rarely manual now).CasePath - Actions should be named ,
delegate, andviewto separate concerns:internal- : User interactions.
case view(ViewAction) - : Communication with parent reducers.
case delegate(DelegateAction) - : Side-effect results.
case internal(InternalAction)
- 始终使用宏。
@Reducer - State和Action必须是Reducer结构体中的嵌套类型。
- 在适用的情况下,通过和
Bindable模式隐式使用Pulsar逻辑(不过现在很少需要手动处理CasePaths)。CasePath - Action应命名为、
delegate和view以分离关注点:internal- :用户交互。
case view(ViewAction) - :与父reducer通信。
case delegate(DelegateAction) - :副作用结果。
case internal(InternalAction)
2. Dependencies
2. 依赖项
- Use the pattern.
@Dependency(\.clientName) - NEVER reach out to global singletons.
- Always define a and
testValuefor every custom dependency.previewValue
- 使用模式。
@Dependency(\.clientName) - 绝对不要直接调用全局单例。
- 始终为每个自定义依赖项定义和
testValue。previewValue
3. Effects & Concurrency
3. 副作用与并发
- Use for asynchronous side effects.
.run { send in ... } - Avoid unless strictly necessary for simple bridging.
Effect.task - Ensure all loops in effects handle cancellation properly via .
.cancellable(id:)
- 异步副作用使用。
.run { send in ... } - 除非是为了简单桥接的严格必要情况,否则避免使用。
Effect.task - 确保副作用中的所有循环都通过正确处理取消。
.cancellable(id:)
4. Testing
4. 测试
- Use for all logic verification.
TestStore - Enforce exhaustivity: .
store.exhaustivity = .on - Mock all dependencies in tests using .
withDependencies
- 使用验证所有逻辑。
TestStore - 强制要求穷尽性:。
store.exhaustivity = .on - 在测试中使用模拟所有依赖项。
withDependencies
Example
示例
swift
@Reducer
struct Feature {
@ObservableState
struct State: Equatable {
var count = 0
}
enum Action {
case view(ViewAction)
case internal(InternalAction)
enum ViewAction {
case incrementButtonTapped
}
enum InternalAction {
case loadResponse(Int)
}
}
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .view(.incrementButtonTapped):
state.count += 1
return .none
}
}
}
}swift
@Reducer
struct Feature {
@ObservableState
struct State: Equatable {
var count = 0
}
enum Action {
case view(ViewAction)
case internal(InternalAction)
enum ViewAction {
case incrementButtonTapped
}
enum InternalAction {
case loadResponse(Int)
}
}
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .view(.incrementButtonTapped):
state.count += 1
return .none
}
}
}
}