You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -13,26 +13,26 @@ SwiftDux helps build SwiftUI-based applications around an [elm-like architecture
13
13
14
14
## State
15
15
16
-
The state is a single, immutable structure acting as the single source of truth within the application.
16
+
The state is an immutable structure acting as the single source of truth within the application.
17
17
18
18
Below is an example of a todo app's state. It has a root `AppState` as well as an ordered list of `TodoState` objects.
19
19
20
20
```swift
21
21
importSwiftDux
22
22
23
-
structAppState: StateTyoe{
23
+
structAppState: Equatable{
24
24
todos: OrderedState<TodoItem>
25
25
}
26
26
27
-
structTodoItem: IdentifiableState{
27
+
structTodoItem: Equatable, Identifiable{
28
28
var id: String,
29
29
var text: String
30
30
}
31
31
```
32
32
33
33
## Actions
34
34
35
-
An action is a description of how the state will change. They're typically dispatched from events in the application. This could be a user interacting with the application or a service API receiving updates. Swift's enum type is ideal for actions, but structs and classes could be used as well.
35
+
An action is a dispatched event to mutate the application's state. Swift's enum type is ideal for actions, but structs and classes could be used as well.
36
36
37
37
```swift
38
38
importSwiftDux
@@ -46,10 +46,7 @@ enum TodoAction: Action {
46
46
47
47
## Reducers
48
48
49
-
A reducer consumes an action to produce a new state. The `Reducer` protocol has two primary methods to override:
50
-
51
-
-`reduce(state:action:)` - For actions supported by the reducer.
52
-
-`reduceNext(state:action:)` - Dispatches an action to any sub-reducers. This method is optional.
49
+
A reducer consumes an action to produce a new state.
53
50
54
51
```swift
55
52
finalclassTodosReducer: Reducer {
@@ -67,34 +64,18 @@ final class TodosReducer: Reducer {
67
64
}
68
65
return state
69
66
}
70
-
71
67
}
72
68
```
73
69
74
-
Here's an example of a root reducer dispatching to a subreducer.
Reducers can also be combined together. This is useful when multiple root reducers are needed, such as two reducers from separate modules.
70
+
Reducers can also be added together to form a composite reducer.
90
71
91
72
```swift
92
73
let combinedReducer = AppReducer + NavigationReducer
93
74
```
94
75
95
76
## Store
96
77
97
-
The store acts as the container of the state. It needs to be initialized with a default state and a root reducer. Then inject it into the application using the `provideStore(_:)` view modifier.
78
+
The store manages the stateand notifies the views of any updates.
The `ConnectableView` protocol provides a slice of the application state to your views using the functions `map(state:)`and `body(props:)`. The `@MappedDispatch` property wrapper injects an `ActionDispatcher` to send actions to the store.
92
+
The `ConnectableView` protocol provides a slice of the application state to your views using the functions `map(state:)`or `map(state:binder:)`.
.onMove { self.dispatch(TodoAction.moveTodos(from: $0, to: $1)) }
128
109
}
129
110
}
130
111
}
131
112
```
132
113
133
-
The view can later be placed like any other.
134
-
135
-
```swift
136
-
structRootView: View {
137
-
138
-
var body: some View {
139
-
TodosView()
140
-
}
141
-
}
142
-
```
143
-
144
114
## ActionBinding<_>
145
115
146
-
SwiftUI has a focus on two-way bindings that connect to a single value source. To support updates through actions, SwiftDux provides a convenient API in the `ConnectableView` protocol using an `ActionBinder` object. Use the `map(state:binder:)` method on the protocol as shown below. It provides a value to the text field and dispatches an action when the text value changes. It also binds a function to a dispatchable action.
116
+
Using the `map(state:binder:)` method on the `ConnectableView` protocol to bind an action to the props object. It can also be used to bind an updatable state value
In some cases, a connected view needs external information to map the state to its props, such as an identifier. Simply add any needed variables to your view and access them in the mapping function.
179
-
180
-
```swift
181
-
structTodoDetailsView: ConnectableView {
182
-
var id: String
183
-
184
-
funcmap(state: TodoList) -> Todo? {
185
-
state[id]
186
-
}
187
-
}
188
-
189
-
// Somewhere else in the view hierarchy:
190
-
191
-
TodoDetailsView(id: "123")
192
-
```
193
-
194
-
## Previewing Connected Views
195
-
To preview a connected view by itself, you can provide a store that contains the parent state and reducer it maps from. This preview is based on a view in the Todo List Example project. Make sure to add `provideStore(_:)` after the connect method.
@@ -253,51 +176,30 @@ let plan = ActionPlan<AppState> { store, completed in
253
176
dispatch(plan)
254
177
```
255
178
256
-
#
257
-
258
-
## Query External Services
259
-
Action plans can be used in conjunction with the `onAppear(dispatch:)` view modifier to connect to external data sources when a view appears. If the action plan returns a publisher, it will automatically cancel when the view disappears. Optionally, use `onAppear(dispatch:cancelOnDisappear:)` if the publisher should continue.
260
-
261
-
Action plans can also subscribe to the store. This is useful when the query needs to be refreshed if the application state changes. Rather than imperatively handling this by re-sending the action plan, it can be done more declaratively within it.
262
-
263
-
Here's an example of an action plan that queries for todos. It updates whenever the filter changes. It also debounces to reduce the amount of queries sent to the external services.
179
+
## Previewing Connected Views
180
+
To preview a connected view by itself use the `provideStore(_:)` method inside the preview.
0 commit comments