I am learning TCA using this link, I am having an issue which is when I tap the fact button, I need to stop the timer and trigger the toggleTimerButtonTapped
action.
I tried to add .cancellable
to .factButtonTapepd
action but it doesn't work. I just want to know what is the right approach here?
case .factButtonTapepd:
state.isLoading = true
state.isTimerRunning = false
return .run { [count = state.count] send in
Task {
let fact = await fetchFact(forCount: count)
await send(.factResponse(fact ?? "nil"))
}
}
.cancellable(id: CancelID.timer)
here is the full code:
func reduce(into state: inout State, action: Action) -> Effect<Action> {
switch action {
case .decrementButtonTapped:
state.count -= 1
state.fact = nil
return .none
case .incrementButtonTapped:
state.count += 1
state.fact = nil
return .none
case .factButtonTapepd:
state.isLoading = true
state.isTimerRunning = false
return .run { [count = state.count] send in
Task {
let fact = await fetchFact(forCount: count)
await send(.factResponse(fact ?? "nil"))
}
}
.cancellable(id: CancelID.timer)
case let .factResponse(fact):
state.fact = fact
state.isLoading = false
return .none
case .toggleTimerButtonTapped:
state.isTimerRunning.toggle()
if state.isTimerRunning {
return .run { send in
while true {
try await Task.sleep(for: .seconds(1))
await send(.timerTick)
}
}
.cancellable(id: CancelID.timer)
} else {
return .cancel(id: CancelID.timer)
}
case .timerTick:
state.count += 1
state.fact = nil
return .none
}
}
}