To cancel ongoing API calls in redux-saga, use takeLatest, race, cancel, and fork.
1. Using takeLatest (Auto-cancel previous):
function* fetchDataSaga() {
yield call(apiCall);
}
function* watchFetch() {
yield takeLatest('FETCH_REQUEST', fetchDataSaga);
}
2. Manual Cancel with fork + cancel:
import { fork, cancel, take, call } from 'redux-saga/effects';
function* fetchDataSaga() {
yield call(apiCall);
}
function* watchFetchWithCancel() {
while (true) {
yield take('FETCH_REQUEST');
const task = yield fork(fetchDataSaga);
const action = yield take(['CANCEL_FETCH', 'FETCH_SUCCESS', 'FETCH_FAILURE']);
if (action.type === 'CANCEL_FETCH') {
yield cancel(task); // Cancel API call
}
}
}
3. Using race (Cancel on timeout or other event):
import { race, call, put } from 'redux-saga/effects';
function* fetchDataSaga() {
const { response, cancelled } = yield race({
response: call(apiCall),
cancelled: take('CANCEL_FETCH'),
});
if (cancelled) {
yield put({ type: 'FETCH_CANCELLED' });
} else {
yield put({ type: 'FETCH_SUCCESS', payload: response });
}
}