Replacing Redux Thunk with Redux Saga
Demonstrate the transition from redux-thunk to redux-saga for managing side-effects with complex async logic in Redux 5.0.0.
import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import { put, takeEvery } from 'redux-saga/effects';
// Action Types
const FETCH_DATA = 'FETCH_DATA';
const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
const FETCH_DATA_FAILURE = 'FETCH_DATA_FAILURE';
// Action Creators
export const fetchData = () => ({ type: FETCH_DATA });
export const fetchDataSuccess = (payload) => ({ type: FETCH_DATA_SUCCESS, payload });
export const fetchDataFailure = (error) => ({ type: FETCH_DATA_FAILURE, error });
// Sagas
function* fetchDataSaga(action) {
try {
const response = yield call(Api.fetchData, action.payload);
yield put(fetchDataSuccess(response.data));
} catch (error) {
yield put(fetchDataFailure(error));
}
}
function* watchFetchData() {
yield takeEvery(FETCH_DATA, fetchDataSaga);
}
const sagaMiddleware = createSagaMiddleware();
// Apply middleware to the store
const store = createStore(
rootReducer,
applyMiddleware(sagaMiddleware)
);
sagaMiddleware.run(watchFetchData);
This snippet sets up the Redux store with Saga middleware replacing Thunk. It creates Saga watchers and workers for the fetch data process.
// rootReducer.js
import { combineReducers } from 'redux';
function dataReducer(state = {}, action) {
switch (action.type) {
case FETCH_DATA_SUCCESS:
return { ...state, data: action.payload };
case FETCH_DATA_FAILURE:
return { ...state, error: action.error };
default:
return state;
}
}
export const rootReducer = combineReducers({
data: dataReducer
});
This snippet shows a root reducer that handles actions for fetching data success and failure.
// Api.js
export const Api = {
fetchData: (payload) => {
// Replace with your API call
return new Promise((resolve, reject) => {
setTimeout(() => {
if (payload) {
resolve({ data: 'Sample data' });
} else {
reject('Error fetching data');
}
}, 1000);
});
}
};
This is a mock API module simulating an async data fetching function.
/* styles.css */
.data-container {
display: flex;
justify-content: center;
align-items: center;
}
CSS styles for a container that will display our data.
<!-- index.html -->
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>Redux Saga Example</title>
<link rel='stylesheet' href='styles.css'>
</head>
<body>
<div id='app'>
<div class='data-container'></div>
</div>
<script src='path/to/your/compiled/javascript.js'></script>
</body>
</html>
This is the HTML file that includes the CSS and the compiled JavaScript, which will make use of Redux Saga for fetching data and updating the UI.