Observables with React.js – 1
The Need
It’s first important to understand the need. I find it very rudimentary to use redux-thunk whereas redux-observables comes with lots of power and prevents you from reinventing the wheel for many use-cases. Let’s take an example:
Say you want to prevent user from launching multiple requests on repetitive button click. With redux-thunk then, you will need to maintain a global state and would need to cancel the previous request after checking if the global was set.
See ? Now imagine doing this for every API request. Clearly, error prone and inefficient.
It can be much elegantly handled if the actions can be transformed into Observables, post which we get many powerful operators such as filtering operators, utility operators and many more at our disposal.
Here you can find an example of debounce handling with RxJS. Type in the search field and see that request is not made unless the user stops typing for a set interval.
(Source: StackOverflow)
Setting up Dependencies
Now as we have understood the need of redux-observables, it’s time to setup the project dependencies. Apart from usual dependencies like React.js, Node.js etc, the two primary dependencies required are:
It can be added to existing project using
npm install @reduxjs/toolkit
Install it using :
npm install --save redux-observable
Once these dependencies are installed we are ready to understand a few important terminologies.
Important Terminologies
1. Redux reducers, actions, store
I assume a basic level of understanding for all above. I want to keep this article about integration of redux and redux-observables hence I will leave you with appropriate links where above concepts can be brushed up. I find this article especially useful to brush-up the basics.
2. Epic
An epic is simply a redux action transformed into a stream. Epic reads a plain redux action and emanates another action and in between of this input and output you can use all RxJs magic which it has to offer. Have a look at the official documentation once and come back.
Understand that redux-observable is a middleware. For ease of understanding, consider it to be working in parallel with redux reducers. That is, whenever a redux action is dispatched it traverse through the redux-observable middleware as well as redux-reducers. Take reference of the code block below, taken from official docs:
In the above code-block, the line “dispatch(fetchUser('torvalds'));
” dispatches a normal redux-action of type defined in the object “{ type: FETCH_USER, payload: username }
“. Since “fetchUserEpic
” will be registered as a middleware, it will be sitting – waiting to get a type of it’s interest. In case of this example this type is declared with “ofType(FETCH_USER)
“.
So once our epic receives an action dispatch of type “FETCH_USER
” it’s going to run the rest of the pipeline and in last would emanate another action after performing side-effects such as ajax call, debouncing etc.
Let’s breakdown what’s happening step-by-step:
- With “
dispatch(fetchUser('torvalds'));
” an action of type “FETCH_USER
” is dispatched. - Since “
FETCH_USER
” is registered with the epic “fetchUserEpic
” on line “ofType(FETCH_USER)
” – it spawn into action an executes the remaining pipeline. - Continuing with the pipeline, “
ajax.getJSON
” is called and an ajax request is made. - Once the response for the ajax request is received, another action dispatcher, “
fetchUserFulfilled
” is called. - “
fetchUserFulfilled
” dispatches “FETCH_USER_FULFILLED
” along with ajax response as payload. - Action from step “5” is received by redux-reducer and state of store is changed.
Moving Forward
We are now ready to understand how to setup a redux store that plays well along with redux-observables. This will be covered in the next post where few other topics such as “slice”, “react-redux hooks” will be touched as well.
Before we wrap up, here’s a glimpse of demonstration of the project that uses redux with observables. It demonstrates a root page where on clicking the button the API is called asynchronously via ajax observable and the state is updated on reception of response.
Also here’s the Github repository for same.
Note: If you try running the application of stackblitz, make sure to first install all dependencies from left pane, before the first run, or else an error will be displayed.