A very basic intro to React redux-saga
By:
Mark Biek
on 1/14/2019
Today, we’re going to do a very brief introduction to Redux-Saga and why it makes React+Redux apps much easier.
To save space, we’ll only be showing the important bits of our app code. Complete, working versions of the app are available on Github:
Basic React+Redux Code
Redux-Saga Code
A Basic App
To see what kinds of problems Redux-Saga helps solve, let’s make a small application that doesn’t use it!
We’ll use a USGS data feed to show a simple list of recent earthquakes.
Here’s our main App
component:
There isn’t anything too weird going on here.
When our component mounts, we make an ajax call to get the data we want. Then that data is dispatched to the Redux store.
Once the store is populated, we display our list.
For a simple example, this is totally fine. For a larger application, however, you can see how this structure isn’t going to scale very well.
If we have lots of ajax calls to make, or we have calls that are dependent on each other, the above approach is going to get ugly in a hurry.
Making it better
The basic idea behind Redux-Saga is that it acts as a separate thread for your application. All of your application side-effects (like ajax calls) go in this thread instead of being called from your components.
You can also watch for certain redux actions use those to trigger other actions.
Behind the scenes, Redux-Saga is using ES6 Generators.These are a powerful programming tool and definitely worth learning, but that’s too much to go into here.
Now let’s update our simple app to use Redux-Saga!
Step 1: Updating the redux store
The first step is updating the redux store to use the saga middleware.
There are a couple of oddities here.
First we haveconst composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
We need that so our app will still work with the Redux Dev Tools extension
The next part iscomposeEnhancers(applyMiddleware(sagaMiddleware))
which applies the saga middleware to our redux store so redux actions actually pass through our saga functions.
And last, we havesagaMiddleware.run(handleLoadQuakes);
sagaMiddleware.run(rootSaga);
The handleLoadQuakes
function contains the code that was previously in the componentDidMount
of our App
component. The sagaMiddlware.run(handleLoadQuakes)
calls that function to do our initial data load.
The second call runs our root saga which will be responsible for watching for any redux actions we’re interested in.
Step 2: Load some data
Let’s take a look at handleLoadQuakes
. As we mentioned before, this will run once when our app first loads.
Notice the *
here?export function* handleLoadQuakes() {
That means that handleLoadQuakes
is a generator function. Almost every saga function you write is going to be defined that way.
The next thing you’ll notice is that we moved our ajax call to a separate (non-generator) function called fetchQuakes
. This function just makes the ajax call and returns the promise from it.
That’s so we can call fetchQuakes
like thislet resp = yield call(fetchQuakes);
The call
is one of the Redux-Saga helper functions. It essentially behaves like calling a function using async-await. Our handleLoadQuakes
will wait until the ajax call finishes before continuing on.
Last but not least, we dispatch a new redux action when the ajax call is completeyield put({ type: 'SET_QUAKES', quakes: resp.data.features, });
One nice thing about the saga approach is it makes it super easy to do loading/error states by updating our handleLoadQuakes
to something like this
Step 3: Watch for some actions
The first part of watching for redux actions is setting up our root saga (the one that we called back up in the redux store).
We define saga functions for any redux actions we want to watch for, then include them in the root saga and the saga middleware takes care of the rest.
In our case, we just have the one function watchRefreshQuakes
which looks like
The magic here is the takeEvery
function. This will listen for every REFRESH_QUAKES redux action that comes through.
The best part is, when a REFRESH_QUAKES action is received, we turn around and call the very same handleLoadQuakes
function we defined previously!
Step 4: The sky is the limit!
Now that we’ve walked through the basics, here are some additional steps you can take:
- Try out the code samples from our Github repository
- Try the Redux-Saga beginner tutorial
- Check out some advanced concepts
Related Posts
Wordpress to Sanity Data Script
By:Nick Stewart on 3/11/2021
One of the biggest challenges of moving from one CMS to another is getting your existing data to the new platform. In our case, we were moving our existing WordPress platform, which had been around for years, over to the Sanity.io platform.
Read More »Developing the New via.studio
By:Alec Robertson on 6/14/2021
A deep dive into creating a fast, user-focused experience on the latest web technology stack for the new via.studio website.
Read More »