Tutorial 3: Advanced Usage - Application Flow Orchestration with Saga
redux-saga
is a great library not only good at handling application side effects such as asynchronous requests but also specialized in dealing with complex application flows.
You can learn more about
redux-saga
from its official documentation
We will run an example to demonstrate how we can use redux-saga to handle side effects with reapex.
Let's continue using the signup form we created earlier and add the following new features:
After signup successfully, log in the user automatically
Provide a
Cancel
button to allow the user to terminate the auto-login if they don't want to get logged in automatically
Let's start with creating a fake login
function to simulate the login request
And we will update the signup
side effect from a promise-based implementation to saga implementation
Here we converted the async/await function to a generator function(assume you have basic knowledge of redux-saga).
We added status
state which indicates the current user login status to the user model.
After successfully signed-up, it will call login
function and mark the user as logged in after login
request returns. The status
state has the initial value LoggedOut
and it will become Logging
when the login
starts and set it to LoggedIn
if successfully logged in.
Accordingly, let's update the UI to reflect the status. A Cancel
button will be shown when login starts and when clicking the button it will terminate the login and reset status to LoggedOut
In order to achieve the above goals, we will need to monitor the Cancel
button click and the login
request at the same time, and if Cancel
happened before login
responded, ignore the login
request and set user as LoggedOut
This is a typical race condition we usually face in FE development. If you're familiar with redux-saga, you will know that we can run a race
effect on Cancel
click and login
request like this:
Please note the second parameter in the tuple returned by mutations
function is the redux action types where we can use the parameter of redux-saga take
See the full example here
Last updated