In case you didn’t read the part one I would recommend you to read it. The first part is covering how to implement the core functionalities of Redux.
At DIY Redux with RxJS => RxDx Part 2, I will reveal the internals of some most popular and widely used Redux middlewares. As I mentioned in the first part of the article -which you can find above-, my goal is to do an experiment to combine RxJS and all widely used Redux middlewares into a library which can be found below:
RxDx
RxDx is a Rxjs base Redux like state management library and it icludes all necessary tooling inside.
heaviliy inspired from great libraries redux, react-redux, redux-observable and ngrx
Motivation
Basic idea behind this library is bringin the full power of RxJS into react world with a familiar interface of Redux withiot relying on some middleware jungle of libraries.
Installation
npm install rxdx --save
or
yarn add rxdx
How to Use
Store
Unlike react-redux RxDx does not rely on context so no need to introduce Provider on App.js. But on the contrary it requires an exported Store to function. In these sample codes it is suggested to have a saperate store.js for initializing the Store and improting it when neccessary. Intentionally the interface of createStore is just like react-redux interface.
//store.js
import {
createStore,
applyMiddleware,
combineReducers,
devToolsMiddleware,
effectsMiddleware
} from "rxdx/lib/rxdx";
import { todoEffects
…Before diving into the subject, it is always good to review the required signature of redux middlewares.
(storeAPI) => (next) => (action) => state
Before I start, I need to confess, when I finished the createStore function I thought with bold confidence that all available middlewares of redux will work for my version of it. Actually, it worked but not for most of them, not for widely used ones :( So I had to provide these libraries/middlewares by re-implementing them or at least implementing similar ones. Here, we go!
A different approach to redux-observable
Under normal conditions, Redux does not implement/has no intention to implement TC39 Observable therefore it is not compatible with RxJS by default.
Here I have to mention the use cases of observables; if you need to operate on streams of events, then it is probably better to use an observable. What kind of operations am I talking on? Merging two streams into one, filtering, mapping or redirecting a stream. For more technical detail check [_here](https://rxjs-dev.firebaseapp.com/guide/observable)._
When implementing a Redux store you will definitely notice that you have to create lots of actions. I have to admit that actions are pretty similar to events and on the runtime, they will be triggered hundreds of times. So this must be the point where redux-observable catches Redux as a streaming event source. By doing so, it creates a good opportunity for developers who are willing to create some asynchronous side effects on each selected action. For detailed documentation on redux-observable , you may check here. TL;DR The magic happens in a function called createEppicsMiddleware that has the signature below:
const createEpicsMiddleware = (rootEpic) => (storeAPI) => (next) => (action) => state
To be honest, when I checked the documentation, I didn’t like the way we need to consume this library. For me, the usage of Effect from NgRx is more classy :) So I decided not to mimic the API of redux-observable, yet the functionality should be there. So I ended up something as follows.
As I mentioned before I really like NgRx style usage and I borrowed Effect decorator and ofType tappable function.
Effect decorator is as simple as adding a type on the original variable. And if your environment supports experimental decorators the usage can be as follows:
@Effect()
const someCoolAsyncSideEffect = action$
.pipe(ofType('SomeCoolAction', 'OrEvenCoolerAction'))
.pipe(map(() => {type: 'SomeOtherCoolAction'}));
Unfortunately, if your environment does not support experimental decorators this code piece won’t look that much handsome.
Reselect
While I was implementing the createStore function in the first part of this story, I implemented a select function in the exposed store object by trusting my gut feeling. This decision revealed itself as pretty useful in implementing the reselect library of RxDx . To be frank, reselect is completely compatible with RxDx , yet I was experimenting and I needed to challenge myself to combine all libraries into it .
What does reselect do? It takes the state or a state portion and returns a portion of it. So what’s the deal? We can achieve the same functionality without it like the example below:
const reselect = (state, key) => state[key];
The example above totally undermines the power of this simple yet incredibly useful library. The deal is, the reselect provides a simple repeatable function which has memoization inside to speed up our -possibly complex- filtering on states.
This function will have a key functionality while we are consuming the RxDx store in react components. The usage of a selector as simple as follows:
Redux Dev Tools Middleware
I thought that the absence of the integration to redux dev tools would be a big missing part of RxDx. Then I started reading the API documentation of dev tools and I found what I need __REDUX_DEVTOOLS_EXTENSION__.connect
After this point, it was super easy to combine everything into a middleware:
Finally, I reached a point which I can create a store, add some reducers, apply built-in optional middlewares and select a specific state child with memoization:
Final words until next time
I strongly recommend such experiments for anybody who wants to learn more about any library or any kind of design patterns or coding styles. It will cause you to question lots of things you do during normal daily coding tasks of yours.
Next time I will continue my experiment with how to combine a redux-like-library with react components and it will include lots of information about HOCs and decorators.
If you are also a self-learner like me and a little bit impatient on top of it, let’s just try it yourself until I release the 3rd and the last part of the RxDx article.
Here is my repo to start your own experiment:
RxDx
RxDx is a Rxjs base Redux like state management library and it icludes all necessary tooling inside.
heaviliy inspired from great libraries redux, react-redux, redux-observable and ngrx
Motivation
Basic idea behind this library is bringin the full power of RxJS into react world with a familiar interface of Redux withiot relying on some middleware jungle of libraries.
Installation
npm install rxdx --save
or
yarn add rxdx
How to Use
Store
Unlike react-redux RxDx does not rely on context so no need to introduce Provider on App.js. But on the contrary it requires an exported Store to function. In these sample codes it is suggested to have a saperate store.js for initializing the Store and improting it when neccessary. Intentionally the interface of createStore is just like react-redux interface.
//store.js
import {
createStore,
applyMiddleware,
combineReducers,
devToolsMiddleware,
effectsMiddleware
} from "rxdx/lib/rxdx";
import { todoEffects
…If you are interested in RxDx and enjoyed the article so far, please don’t forget show your appreciation. If you share your ideas and feedback below, I would only be glad!
Thanks for reading!
This post originally published on hanckernoon.com. On dev.to it is slightly adapted to platform
DIY Redux with RxJS: Part 3 on hackernoon
Top comments (0)