Using redux-observable on NextJS
By: Miguel Q
Tags: Nextjs, Rxjs, React, Redux, Redux Observable

Some context

One of the key NextJS features is the getInitialProps static method which allows us to provide the initial props needed by the component. Also, you can return a promise to load asynchronous data before the render happens. This example below shows how easily we can provide a prop to the component (in this case props.name ).

Another simple example is using a Promise to load asynchronous data (i.e from server). In this case NextJS will just render after this promise is resolved.

As you can see in these examples above it’s very easy to pass data from the getInitialData to the component even if that data needs to be loaded asynchronously.

The problem with this

Now if we add redux and redux-observable to this equation things start getting more complicated. Mainly because all the side-effects will be handled by your epics and getInitialProps is just able to handle promises. Although NextJS provides an example of how we can use redux-observables in a NextJS application. I think that solution in a real scenario where we have lots of epics separated from the components and we need to rely on several epics to handle all data required, this solution is not enough. Primarily because you will have to import rootEpic and implement this logic across your application which is far from ideal.

Solution

The solution is based in two libraries which will together simplify your life. The first one is next-redux-wrapper that will connect your NextJS application with a redux store (also used on the NextJS example). Then you need to integrate next-redux-observable which will “connect” your epics with your application. In other words, you will need to provide your rootEpic through the HOC withObservable which then will push the actions needed into that stream ( rootEpic ).

use withObservable on pages/_app.js where you will provide your rootEpic ;

on where you will provide your ; use resolveActions on your “pages” components where you will just need to provide which actions need to be loaded on a particular page component.

This might sound complicated or vague but it’s really easy so let's do it step-by-step. First let's implement our actions, reducer, and epic 🚀

Now let’s create our store as any redux application. One thing to note here is that we are combining our epics and exporting them because we will need it on pages/_app.js .

Now we need to override pages/_app.js file as you can see on next-redux-wrapper documentation. Apart from the changes suggested by next-redux-wrapper we just need to add withObservable providing our rootEpic (line 33).

At this point, we have everything we need. Let’s create a page that needs to load the user’s data. In other words, we need to dispatch NS/USER/LOAD action and wait for that action to be finished.

How cool is this 👏? The key point here is the method resolveActions that gets a list of actions that behind the scenes will be dispatched. Then it will wait for all of those actions to finish and to then resolve its promise (expected by getInitialProps ) 🔥

If you are struggling to follow the steps no need for panicking just check out the example project which you can clone and run on your machine 🤓.

Conclusion

I do understand that most of the NextJS projects do not need RxJS or even Redux to manage the data needed to render its components. Anyway, if your project needs to use RxJS I do believe that using next-redux-observable will make your code much easier to implement and to maintain.