SwiftUIRedux
Comprehensive Redux library for SwiftUI.
- Keep
State
consistent acrossStores
by type safepub/sub
pattern withReducers
ofRootStore
. - Waterfall
Action
propagation flow from root toState
subtree.
Unidirectional Data Flow
-
RootStore/Dispatcher: Propagates domained actions
-
Reducer: Subscribes to
RootStore
and reducesAction
to generate new state -
Action: Action driven - more loosely coupled pattern than
Delegation
pattern -
State:
- Reduces
Action
and outputs newState
- Waterfall reduce flow: propagates
Action
to children nodes viaState
tree
- Reduces
Declarative/Stateful/Immutable/Predictable
- Efficient tree diff algorithm, no more imperative manual update code.
Usage Example
FeedListView
struct FeedListView: View {
@ObservedObject var state = FeedListState()
var body: some View {
List {
ForEach(state.feeds, id: \.diffId) { feed in
FeedCell(feed: feed)
}
}
}
}
FeedListState
public class FeedListState: ReduxReducer, ObservableObject {
@Published var feeds: [Feed] = []
public override func reduce(action: ReduxActionProtocol) {
// Propagates `action` to the substate tree.
// Setting `self.feeds` with new feeds triggers list UI reloading
// and SwiftUI will diff efficiently based on list identifier.
feeds = feeds.map { $0.reduce(action: action) }
}
Dispatch FeedLikeAction
dispatch(action: FeedLikeAction(feed: feed))
Reduce FeedLikeAction
public struct Feed {
public var diffId = UUID()
public let feedId: Int
public let title: String
public var isLiked: Bool { didSet { diffId = UUID() } }
}
extension Feed: ReduxStateProtocol {
@discardableResult
public func reduce(action: ReduxActionProtocol) -> Self {
// Makes the deep copy of self.
var feedCopy = self
switch action {
case let action as FeedLikeAction:
// Reduces the `FeedLikeAction`.
if feedId == action.feed.feedId {
feedCopy.isLiked = !action.feed.isLiked
}
default: break
}
return feedCopy
}
}