Learn about state-driven navigation in TCA, including tree-based and stack-based approaches
State-driven navigation is a powerful concept in application development. The Composable Architecture provides tools to model your domains concisely and drive navigation from state.
For the purposes of this documentation, we use the following definition:
Navigation is a change of mode in the application.
Each form of navigation—drill-downs, sheets, popovers, covers, alerts, dialogs, and more—represents a “change of mode” in the application. More specifically:
A change of mode is when some piece of state goes from not existing to existing, or vice-versa.
When a piece of state switches from not existing to existing, that represents navigation and a change of mode. When it switches back to not existing, it represents undoing the navigation.
Tree-based navigation uses Swift’s Optional type to represent existence or non-existence of state. When multiple states of navigation are nested, they form a tree-like structure.
Here’s how a typical app might combine both approaches:
@Reducerstruct AppFeature { @ObservableState struct State { // Stack-based navigation for main flow var path = StackState<Path.State>() } @Reducer enum Path { case home(HomeFeature) case profile(ProfileFeature) }}@Reducerstruct HomeFeature { @ObservableState struct State { // Tree-based navigation for modals @Presents var settings: SettingsFeature.State? @Presents var alert: AlertState<Action.Alert>? }}
This hybrid approach gives you the best of both worlds: a flexible main navigation flow with well-defined modal presentations.