Build a simple app that dog images using React, Redux & Redux-Saga fetches Michael Gil — https://www.flickr.com/photos/msvg/ I began using at work in a . [redux-saga](https://redux-saga.js.org/) fairly complex boilerplate The path to becoming even a little bit comfortable with it was winding and suboptimal, so I thought I’d write the tutorial I wish I’d had when just starting out with sagas. This tutorial assumes you have a solid grasp of React or React Native and Redux. If you’re not ready for (yet), I’d definitely recommend that you check out this amazing, MASSIVE treasure trove of resources for learning React and Redux. redux-saga _react-redux-links — Curated tutorial and resource links I’ve collected on React, Redux, ES6, and more_github.com markerikson/react-redux-links What you’ll build _Super simple app for a beginner redux-saga tutorial._ryanjyost.github.io Dog Saga - Redux-Saga Beginner Tutorial What’s redux-saga? Why would I want or need it? From the : official repo is a library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage, more efficient to execute, simple to test, and better at handling failures. redux-saga I think of it as an organized way of helping your Redux app communicate and stay in-sync with the outside world — mainly external APIs. Many wonderful people have opined on the pros, cons, and everything else about , much better than I could — so here are some links if you want to really nail down the and redux-saga WHATs WHYs. We’ll be focusing on the . HOW _The mental model is that a saga is like a separate thread in your application that's solely responsible for side…_redux-saga.js.org Read Me · Redux-Saga _For me, there has always been one thorn in the React+Flux setup, which is that more complicated processes involving…_jaysoo.ca Managing Side Effects In React + Redux Using Sagas _WTF is a clock? (This is the first post in a three-part introduction to Redux Saga. The second post is here, and the…_ohyayanotherblog.ghost.io Redux Saga: The Future is 1975 _Some of the most fragile, embarrassing, and unreadable code you will write is flow control. — Beowulf_shift.infinite.red Using redux-saga To Simplify Your Growing React Native Codebase _Redux-saga is a redux middleware library, that is designed to make handling side effects in your redux app nice and…_engineering.universe.com What is Redux-Saga? _There's this expression I say each time I stumble on something (some technology) that's going to change my habits in…_riad.blog Redux nowadays : From actions creators to sagas _Learn how to handle intricate procedures with async watcher routines (sagas) that monitor your Redux events. Brandon…_konkle.us Master Complex Redux Workflows with Sagas Let’s get started Create a new app with . [create-react-app](https://github.com/facebookincubator/create-react-app) npx create-react-app dog-saga Confused by the ? So was I, until I read . npx this Enter the project’s directory and fire up the app. cd dog-saganpm start You should now see the boilerplate for , with it’s spinning React logo. You’ll be replacing it with cute dogs soon enough. create-react-app Redux Install redux. npm install --save redux Create a new file in your folder called and add the following code to it. src redux.js We have three action types and a single reducer says that we’re beginning the process of a dog from the . **API_CALL_REQUEST** fetching Dog API tells the Store that we successfully retrieved a and are therefore no longer in the process of one. **API_CALL_SUCCESS** dog fetching tells the Store that something went wrong with our API call. We received an rather than a new . **API_CALL_FAILURE** error dog But how should we make the ? API_CALL_REQUEST How does the Store know whether the API call was a success or a failure? HOW DO WE GET PICTURES OF CUTE DOGS DAMNIT??? With a saga. P.S. We’re not gonna use action creators in this app. For something so simple, they may muddy the waters. Also, you’ll see how redux-saga handles and dispatches actions more clearly (in my opinion) without them. Redux-Saga We want to create a , using , that will initiate an API call for a dog image, then tell the Store whether that API call was a success or a failure. saga redux-saga If successful, we’ll get a new and dispatch along with the . dog API_CALL_SUCCESS dog If a failure, we’ll get an and dispatch along with the . error API_CALL_FAILURE error Install . redux-saga npm install --save redux-saga Also install , which will help us make -based API calls. [axios](https://github.com/axios/axios) [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) npm install axios Create a new file called and add the following code to it. sagas.js Before we walk through this new file, notice the syntax. This creates a special kind of function new to ES6 called a . function* [generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*) Generators can pause and restart — be exited and re-entered — and actually remember the context/state of the function over time. Each in a generator basically represents an asynchronous step in a more synchronous/sequential process — like in an function. yield somewhat await [async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) relies on generators, but does a decent amount of the work for us, so (in my fairly limited experience) a deep understanding of them for this use-case isn’t necessary. redux-saga Here are some resources if you want to learn more about generators _ES6 Generators: Complete Series The Basics Of ES6 Generators Diving Deeper With ES6 Generators Going Async With ES6…_davidwalsh.name The Basics Of ES6 Generators _In 7 Surprising Things I Learned Writing a Fibonacci Generator in JavaScript, I covered one obvious use-case for ES6…_medium.com The Hidden Power of ES6 Generators: Observable Async Flow Control Now let’s walk through **sagas.js** a is a saga that for an action to be dispatched to the Store, triggering a . **watcherSaga** watches workerSaga is a helper function provided by that will trigger a new when it sees an , while cancelling any previously triggered still in process. [takeLatest](https://github.com/redux-saga/redux-saga/tree/master/docs/api#takelatestpattern-saga-args) redux-saga workerSaga API_CALL_REQUEST workerSaga simply uses to request a random dog image from the Dog API and returns a for the response. **fetchDog** axios [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) attempts to , using another helper function , and stores the result (a resolved or failed ) in a variable. **workerSaga** fetchDog redux-saga [call](https://github.com/redux-saga/redux-saga/tree/master/docs/api#callfn-args) Promise response If was a success, we extract the image from the and dispatch an action with in the payload to the Store, using ANOTHER helper function . fetchDog dog response API_CALL_SUCCESS dog redux-saga [put](https://github.com/redux-saga/redux-saga/tree/master/docs/api#putaction) If there was an error with , we let the Store know about it by dispatching an action with the . fetchDog API_CALL_FAILURE error Phew! It’s a little weird at the beginning, but this pattern/procedure and its benefits become more clear after a few implementations. Hook up React, Redux and Redux-Saga Ok, we have our pieces, now it’s time to put them all together. Install . [react-redux](https://github.com/reactjs/react-redux) npm install --save react-redux Also, install Redux Devtools — must-have for debugging and seeing Redux (and sagas’ related actions) in action. I recommend using the . Go here for info on setting up the Redux dev tools. browser extension Open your file and make it look like the file below. index.js The Redux stuff should look familiar. with our [createStore](https://github.com/reactjs/redux/blob/master/docs/api/createStore.md) reducer Connect the to the Store for debugging and learning Redux DevTools And wrap the component in a component with the , which let’s us work with Redux React. <App/> <Provider/> store in We’ll actually _connect()_ the _<App/>_ component shortly. To make our work with Redux… redux-saga , and apply it to the Redux with some help from and createSagaMiddleware store [compose](https://github.com/reactjs/redux/blob/master/docs/api/compose.md) [applyMiddleware](https://redux.js.org/docs/api/applyMiddleware.html) the , so that it can trigger the when there’s an run watcherSaga workerSaga API_CALL_REQUEST Connect <App /> to Redux Open up and paste the following code into it. App.js to make the most current state of , and available as in the component. mapStateToProps fetching dog error props App Using , we create a function called that dispatches an action to the Store. mapDispatchToProps onRequestDog API_CALL_REQUEST the component and export this “reduxed” version of it for use in . connect App index.js Bring it all together on the screen Now let’s walk through some of the changes made to the component’s rendered output, which allow the user to see the current state of the app and request dog images. (top to bottom) App All of these snippets are from the **App.js** above, so no new code here. In the snippet below, we tweaked the image to show a image if one exists in the Store. If is , it falls back to the React . src dog dog null logo If the current of our app has a image, we tell the user to keep clicking. If not, we tell them to replace the React with a . state dog logo dog If the current has an error, we display some text to let the user know. state Here, if our sagas are currently in the process of a new dog image, which means has not dispatched an or yet, we disable the button. fetching workerSaga API_CALL_SUCCESS API_CALL_FAILURE Otherwise, we provide a button for the user to click and request a random dog image. Just for fun, let’s cause an error To see the dispatch an , go into and mess up the for the dog api (like changing “breeds” to “beds”). workerSaga API_CALL_FAILURE sagas.js url Now when you click the “Request a Dog” button, the error message displays! A recap, step-by-step An event takes place — e.g. user does something (clicks “Request a Dog” button) or an update occurs (like ) componentDidMount Based on the event, an is dispatched, likely through a function declared in (e.g. ) action mapDispatchToProps onRequestDog A sees the and triggers a . watcherSaga action workerSaga Use saga helpers to watch for actions differently. the saga is starting, the also hits a and updates some piece of to indicate that the saga has begun and is in process (e.g. ). While action reducer state fetching The performs some side-effect operation (e.g. ). workerSaga fetchDog Based on the result of the ‘s operation, it dispatches an to indicate that result. If successful ( ), you might include a payload in the action (e.g. ). If an error ( ), you might send along an object for more details on what went wrong. workerSaga action API_CALL_SUCCESS dog API_CALL_FAILURE error The handles the success or failure from the and updates the Store accordingly with any new data, as well as sets the “in process” indicator (e.g. ) to false. reducer action workerSaga fetching Throughout this process, you can use the updates to Redux flowing through to to keep your user informed of the process and progress thereof. state props More resources _UPDATE August/2017:_medium.freecodecamp.org Async operations using redux-saga _This is a 2-part series — feel free to check out the first part here._medium.freecodecamp.org This collection of common Redux-saga patterns will make your life easier.