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