Store
TheStore is the runtime that powers your TCA application. It holds the current state, processes actions through reducers, and executes effects. You typically create one store at the root of your application and pass scoped versions to child views.
The Store Type
Store.swift
Creating a Store
Basic Initialization
Create a store with initial state and a reducer:App.swift
With Dependencies
Override dependencies at store creation:Accessing State
In SwiftUI Views
Access state directly from the store when using@ObservableState:
FeatureView.swift
With
@ObservableState, you don’t need @ObservedObject or other property wrappers. The store integrates with Swift’s Observation framework.Using withState
For non-observable contexts or when you need a snapshot:Sending Actions
Send actions to the store to trigger state changes:With Animation
With Transaction
Scoping
Thescope method transforms a store to work with a subset of state and actions:
Store.swift
Basic Scoping
AppView.swift
Why Scoping?
Modularity
Views only access the state they need
Type Safety
Compiler ensures child views can’t access parent state
Performance
Views only re-render when their slice of state changes
Testability
Child features can be tested in isolation
Store Task
TheStoreTask type represents the lifecycle of effects:
Store.swift
Awaiting Effects
Tie effect lifecycle to SwiftUI’s.task modifier:
When the view disappears, the task is automatically cancelled, which cancels the effect.
Manual Cancellation
Store Publisher
For Combine-based observation:With
@ObservableState, prefer using Swift’s Observation framework over Combine publishers.StoreOf Type Alias
UseStoreOf for more concise type signatures:
Store.swift
Observation
TCA integrates with Swift’s Observation framework:iOS 17+
Automatic observation using Swift’s nativeObservable protocol:
iOS 13-16
Uses the Perception library for backward compatibility:Testing Stores
UseTestStore for testing:
FeatureTests.swift
Store Lifecycle
Initialization
- Store is created with initial state
- Dependencies are prepared
- Reducer is configured
- State observation is set up
Action Processing
- Action is sent via
store.send() - Reducer processes action, mutating state
- Effects are executed
- Observers are notified of state changes
Deinitialization
- All running effects are cancelled
- Child stores are deallocated
- Observations are cleaned up
Best Practices
1
Create Store at App Root
Create a single store in your app’s entry point:
2
Scope to Child Views
Use
scope to pass focused stores to children:3
Avoid State Copies
Don’t copy state out of the store:
4
Use @ObservableState
Always apply
@ObservableState to your state types:Common Patterns
Optional Child Stores
Scope to optional child state:Store in @StateObject
For creating stores in SwiftUI views:Multiple Store Instances
For previews or isolated features:Related Topics
- State Management - Understanding state
- Reducers - How actions are processed
- Effects - Side effects executed by the store
- Testing - Testing with TestStore