Overview
The@ObservableState macro implements SwiftUI’s Observable protocol for your reducer’s state, enabling efficient view updates when state changes. This is the recommended way to make your feature’s state observable in SwiftUI.
The macro generates:
- Conformance to Swift’s
Observableand TCA’sObservableStateprotocols - Internal observation tracking infrastructure (
_$observationRegistrar,_$id,_$willModify) - Automatic property observation for all stored properties
- Integration with TCA’s state change notification system
Basic Usage
Apply@ObservableState to your reducer’s State type:
@Bindable to create bindings:
Why Use @ObservableState?
Without@ObservableState, you need to manually observe the store using observe in your views, which can be verbose and error-prone. The macro provides:
- Automatic observation: Views automatically update when observed state changes
- Fine-grained updates: Only views observing changed properties re-render
- SwiftUI integration: Works seamlessly with SwiftUI’s observation system
- Type safety: Compile-time guarantees about observable properties
Controlling Observation
You can control which properties are observed using helper macros:@ObservationStateTracked
Explicitly marks a property as tracked (this is the default for all stored properties):@ObservationStateIgnored
Marks a property to ignore for observation. Use this for properties that shouldn’t trigger view updates:internalCache or debugInfo change, only when displayedCount changes.
Working with Nested State
When composing features, apply@ObservableState to each feature’s state:
Using with @Presents
For presented features, use the@Presents macro instead of the PresentationState property wrapper:
The
@Presents macro is required when using @ObservableState because property wrappers like PresentationState are incompatible with Swift’s observation system.Collections and Identified Arrays
The macro works seamlessly with collections:items will update when the array changes.
Performance Considerations
The@ObservableState macro is designed for performance:
- Structural identity: Each state value has a unique identifier for efficient change detection
- Willset notifications: Observers are notified before mutations occur
- Minimal overhead: Only properties actually accessed by views are tracked
Migration from ViewStore
If you’re migrating from the olderViewStore pattern:
Before:
See Also
- Reducer Macro - Define features with the @Reducer macro
- @Presents Macro - Present child features
- Observation Integration - Observation system details