Reducer
A reducer is a function that is passed the current state, an event and the environment and can return an optional effect. The reducer's role is to act upon (or not) the event.
The reducer should be as performant as possible, any long running task should performed by an effect.
These are the events from our example Twitter app.
enum AppEvent {
case viewDidAppear
case fetchTimeline
case didFetchTimeline([Tweet])
case failedFetchingTimeline(Error)
}
and this is the state:
struct AppState {
var timeline: [Tweet] = []
var followers: [User] = []
var following: [User] = []
}
extension AppState: Equatable {}
Focussing on the timeline events, the plan here is that fetchTimeline
will trigger an API request and then on success or fail the events didFetchTimeline
or failedFetchingTimeline
will be called. On didFetchTimeline
the reducer will update the states timeline
value.
let reducer: Reducer<AppState, AppEvent, AppEnvironment> = Reducer { state, event, environment in
switch event {
case .fetchTimeline:
return Effect {
do {
let tweets = try await environment.apiClient.fetchTweets()
return .didFetchTimeline(tweets)
} catch {
return .failedFetchingTimeline(error)
}
}
case .didFetchTimeline(let tweets):
state.timeline = tweets
return .none
case .failedFetchingTimeline(let error):
// Do something with the error...
return .none
}
}
Combining reducers
TODO
Optional reducers
TODO