What is Redux-Saga?
Redux-Saga, like Thunk, is a redux middleware for React/Redux application. With the help of Redux-Saga, the side effect becomes easier to manage, more efficient to execute, simple to test and better at handling the failures. It has access to the full redux application state and it can dispatch redux actions. Unlike thunk, its thread can be started, paused and canceled from the main application with normal redux actions.
How do we implement Redux-Saga?
To make the implementation easy to understand, I’ll use my basic React/Redux weather app, to check the 7 days weather forecast of the selected city with the help of One Call API.
$ npm install --save redux-saga
$ yarn add redux-saga
2. Import Redux-Saga to the store configuration
To run saga, we need to connect saga with Redux store using createSagaMiddleware.
3. Create action file
To fetch weather from One call API, we dispatch two plain object actions, “REQUEST_API_DATA” handles when the API call is initiated, “RECEIVE_API_DATA” is passed down to reducer.
4. Saga file
In saga file, we make sure it watches for watches for all “REQUEST_API_DATA” actions and triggers an API call to fetch the user data. Redux Saga has effect, an object that contains some information to be interpreted by the middleware. To create effects, we use functions provided by the library in the “redux-saga/effects”.
call(fn, …args): creates and Effect description that instructs the middleware to call the function with argument. Like the example below, when “REQUEST_API_DATA” is dispatched, the fetchData function is called with the action.data as an argument.
put(action): creates an Effect description that instructs the middleware to schedule the dispatching of an action to the store. We dispatch the receiveApiData action in the below example.
fork(fn, …args): creates an Effect description that instructs the middleware to perform a non-blocking call. In the following example, rootSaga might contains multiple sagas, so I used fork to call non-blocking function.
takeLatest(pattern, saga, …args): forks a saga on each action dispatched to the Store that matches pattern. And automatically cancels any previous saga task started previously if it’s still running. Personally, I used takeLatest here to avoid multiple running fetches.
takeEvery is commonly used in the production.
takeEvery(pattern, saga, …args): spawns a saga on each action dispatched to the Store that matches pattern.
For “DRY” reason, I set an api file to exclusively handle api fetching.
After we dispatch the “RECEIVE_API_DATA” action to the reducer, we’ll set state in the reducer file. We will get an array of 7 days forecast objects of a city of your choosing.
Compare to other redux middleware, it supports async operations better. With the help of effect creators, saga makes the side effect management more efficient and effective. So in the future, Redux-Saga might be a better choice for Redux middleware.