⚠️ This lesson is retired and might contain outdated information.

Handle Side Effects with Redux Saga Generator Functions

Tyler Clark
InstructorTyler Clark
Share this video with your friends

Social Share Links

Send Tweet
Published 7 years ago
Updated 2 years ago

In this lesson we’ll fetch the star wars api and display the response to our UI. Saga effects and generators allow us to synchronously run asynchronous tasks.

Instructor: [00:00] We have a basic React and Redux application. Inside this div, we want to map over our "Star Wars" reducer and print to the page a list of Star Wars characters' names under the title.

[00:12] This will be initiated when clicking on this "Load more" button which you can see in the UI. We need to add an onClick handler. This will be calling the fetch Star Wars request action creator that you can see we are getting through props already.

[00:27] However, when we click on the button, nothing is happening. This is where we want redux-saga to listen to the store.dispatch of fetch Star Wars request and do two things. The first is send an AJAX request to the Star Wars API. The second is to dispatch a success action that will carry the response data to our reducer and get picked up by a UI here.

[00:47] Now we'll navigate to our actions file and import call and put from redux-saga/effects. As you can see, we already have this fetch Star Wars request action creator. This is what's dispatched when we click on that "Load more" button from the UI.

[01:03] Now we can create our Saga generator function. We're going to export it and call it fetchPerson. It receives an action object. We want to use a try/catch so we can handle any errors. We want to do const person equals yield call API and a string URL.

[01:24] Both call and put are referred to as object effects by redux-saga. Here we're assigning the yielded value to const person so that we can use it later inside of our function. The first parameter is a function. The rest of the provided call parameters will be spread out into this API function. Call will return whatever the provided function returns.

[01:47] Let's make this function up here at the top. We'll do const API where it will receive this URL as a parameter and the ES6 fetch where we'll return the unwrapped promise. Now that we have the API part set up, we need to yield put an action creator with a type and a data property.

[02:10] The put effect works just like the Redux store.dispatch. Here we're actually dispatching this action creator with the fetch Star Wars success type and the results from our previous API call. If our reducers that are connected to the store have logic to accept this type, it will use this data to print to the UI.

[02:33] The beauty of redux-saga is it utilizes the yield keyword to suspend dispatching this action creator until the fetch promise has resolved, thus making asynchronous things, like fetch in our case, synchronously.

[02:47] It's also important to know that fetchPerson will automatically receive the action that initiated it. This action here, when dispatched, will invoke fetchPerson. This is handy because sometimes we need to pass through case-by-case information that's needed inside effects.

[03:04] We'll finish up by adding a console log inside of our cache to log out any errors we might get if our Star Wars API fetch fails. We can also use the put effect to dispatch an error action to display a message to your user.

PCR IT Training
PCR IT Training
~ 6 years ago

Anyone else having trouble with the import { call, put } from 'redux-saga/effects';? I found this https://github.com/brunch/brunch/issues/1695 whihc also has a similar issue linked in the thread. It seems that a workaround is import { call, put } from 'redux-saga/lib/effects';

tnl-matt
tnl-matt
~ 6 years ago

I had problems with npm install (npm v6.7.0) and ended up installing everything from scratch. In case this helps anyone, here's my resulting package.json. Also, the lecture appears to start with the master branch.

{
  "name": "sagas",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.0.0",
    "react-dom": "^16.7.0",
    "react-redux": "^6.0.0",
    "react-scripts": "^2.1.3",
    "redux": "^4.0.1",
    "redux-saga": "^1.0.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {
    "redux-devtools": "^3.5.0"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}
Lauro Silva
Lauro Silva
~ 5 years ago

Further context of this application can be found in the source code and by exploring the different branches: https://github.com/twclark0/redux-sagas-gh/tree/simple-saga-example

Note, as Matt mentioned in the previous comment, install npm i npm@6.7.0.

Markdown supported.
Become a member to join the discussionEnroll Today