Orchestrating Long-running Processes with Saga
Illustrate the use of sagas to manage complex, long-running processes such as a file upload progress indicator, using a combination of 'take', 'fork', 'put', and 'cancelled' effects to provide real-time feedback to the user.
import { take, fork, put, call, cancel, cancelled } from 'redux-saga/effects';
import { fileUploadActions } from './actions';
function* uploadFileSaga(action) {
const { file } = action.payload;
try {
const task = yield fork(handleFileUpload, file);
yield put(fileUploadActions.uploadStart());
const fileUrl = yield task;
yield put(fileUploadActions.uploadSuccess(fileUrl));
} catch (error) {
yield put(fileUploadActions.uploadFailure(error.toString()));
} finally {
if (yield cancelled()) {
yield put(fileUploadActions.uploadCancelled());
}
}
}
This saga listens for a file upload action, forks a task to handle the upload, and manages the upload state. It updates the state to reflect the start, success, failure, and cancellation of the upload.
import { call } from 'redux-saga/effects';
async function handleFileUpload(file) {
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/upload', { method: 'POST', body: formData });
if (!response.ok) throw new Error('Upload failed');
return response.json();
}
function* watchFileUpload() {
while (true) {
const action = yield take(fileUploadActions.uploadRequest().type);
yield call(uploadFileSaga, action);
}
}
Defines the asynchronous file upload handler and a watcher saga. The handler encapsulates the upload logic, while the watcher listens for upload requests and triggers the upload saga.