The call effect, which is used to invoke async functions (like retrieving data) inside sagas, can be used to leverage async functions in Redux-Saga middleware with React.
Using Async Functions in Redux-Saga with React: A Guide
First, install Redux-Saga:
npm install redux-saga
Set Up the Redux Store and Saga Middleware:
Connect the Redux store to the React application after setting it up with SagaMiddleware.
import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './reducers';
import rootSaga from './sagas';
// Create saga middleware
const sagaMiddleware = createSagaMiddleware();
// Create store and apply middleware
const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));
// Run the saga
sagaMiddleware.run(rootSaga);
export default store;
Create Your Sagas (Async Functions):
You can use call from redux-saga/effects to invoke async functions (like API calls).
sagas.js (Example):
import { takeEvery, call, put } from 'redux-saga/effects';
import axios from 'axios';
// Example of an async function (API call)
const fetchData = async () => {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
return response.data;
};
// Worker saga to fetch data
function* fetchPosts() {
try {
// Call the async function
const posts = yield call(fetchData);
// Dispatch the action with the fetched data
yield put({ type: 'FETCH_POSTS_SUCCESS', posts });
} catch (error) {
// Dispatch the error action if the API call fails
yield put({ type: 'FETCH_POSTS_FAILURE', error });
}
}
// Watcher saga to listen for specific actions
function* watchFetchPosts() {
yield takeEvery('FETCH_POSTS_REQUEST', fetchPosts);
}
// Export the root saga
export default watchFetchPosts;
Dispatch Actions from React Components:
In your React components, dispatch the action to trigger the saga.
App.js (Example):
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
const App = () => {
const dispatch = useDispatch();
const posts = useSelector(state => state.posts);
const error = useSelector(state => state.error);
useEffect(() => {
// Dispatch action to fetch posts
dispatch({ type: 'FETCH_POSTS_REQUEST' });
}, [dispatch]);
if (error) {
return <div>Error: {error}</div>;
}
return (
<div>
<h1>Posts</h1>
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
};
export default App;