In this article we’ll go over setting up a simple web app that will handle asynchronously fetching data from a public api using redux saga (we’ll use https://thecatapi.com/). By the end of this walk though you should have an understanding of how to handle asynchronous actions using redux-saga. We will build an app that fetches a random cat image.
Feel free to use this article as a reference for setting up new projects using redux-saga!
0. Create a React app (if you don’t already have one)
If you don’t already have a react app it’s really easy to create one (for more info on create-react-app see https://github.com/facebook/create-react-app):
If you’re integrating redux saga into your own project, feel free to skip this step, or use a different view library all together!
npx create-react-app my-app && cd my-app
1. Install dependencies
You’ll need the following additional packages:
reselect(optional, feel free to use a different selector strategy)
react-redux(optional, if you’re not using react you’ll need a different connector)
axios(optional, we’re going to use axios for making our http requests, but feel free to use something else)
npm install --save redux redux-saga reselect axios
2. Actions (and action creators)
I personally prefer to declare my action types as consts in a dedicated const.js file:
…and the action creators, we’ll use these later to describe events that occur within our app:
Our reducer will receive every action that is dispatched and its job is to return a new state. Apps can have multiple reducers that are typically responsible for an individual part of state (commonly referred to as slices). For our app we’ll just have one reducer that will handle the three action types we declared:
Our saga will describe the asynchronous workflow that needs to be performed in response to our
FETCH_CAT action. Then we will dispatch new actions based on the outcome of our execution. A few notes on the redux-saga api (complete documentation can be found here: https://redux-saga.js.org/):
takeLatestwill run the associated generator function for only the latest dispatched
callis pretty much what it sounds like, it calls the function specified by the first argument (
axios.getin our case ) with the parameters in the next argument which is an array. This basically allows us to use our promise with
putis similar to call but it calls Redux's
What is nice about this is that it is a fairly readable representation of our asynchronous logic without the nesting required by promises.
- We call the api at the url for the api store the response in our variable
responsewhen it is completed
- Once the response is received we
dispatcha new action describing the event (we got a response from the api)
- If there is an error (line 9 will throw an error if the api responds with an error) we
dispatchan new action describing that event (there was an error fetching the cat)
Now we need to make sure that our reducers and sagas are added to our redux store. This is just a bit of plumbing to make sure that redux’s
- We create a root saga, just named
sagathat yields all of our exported sagas, basically just runs all of our generators so they are ready to receive actions.
- We set up our redux store as normal with our combined reducers.
- We call create store and export the resulting store as default so it can be used in our application.
- Finally we instruct the saga middleware to run
6. View layer
Now our view layer will look pretty much like any normal react-redux container. We map dispatch and any selectors we need to our component and then use them in the component.
Thats it, now you have a functioning app that asynchronously fetches random cat images.