Actions, Messages and Streams

Redux way

Redux is about passing actions (IMHO - they should be named messages. They are not active, they are just data). Each action/message carries data what happened, like "user clicked here", "this data arrived" etc.

const action = {
  type: 'user_added',
  data: 'A'
}

This is typical action in Redux and you can create actionCreator's function that will generate it and then call it like userAdded('A').

To get messages "at work" we need them to dispatch in Redux. dispatch means that the message hits the place where it will be processed (reducer/s). dispatch is a function of the Store and therefore we somehow need it to be available when we want to dispatch.

RxJS / RxR way

For our RxJS implementation let's think about slightly different concept - streams.

Imagine them as a unix pipes like cat thisFile.txt | grep "TODO" | .... Or if you want more javascript-like example, they are little bit like map function.

The left ("in") part of the stream/pipe acts as an Observer. It observes everything you put in. Observer means that it will get it and may send it further - to the right side.

The right side ("out") part of the stream is Observable. That means it sometimes emits the data (when some other Observer will ask for them).

In RxJS are not only these double sided streams like this but in this example are good for two reasons

1) we explained Observer and Observable (and when the stream is both, it is Subject) 2) Redux actions (or actionCreators) modeled in Rx are actually Subjects

So let's model our Redux counterpart of actions or actionsCreators as

const userAdded$ = new Rx.Subject;

Note: We will use the convention that Rx streams when assigned to variables will end with '$'. They don't have to but if you see something like variable$, you can guess that it is not usual object but Observable stream.

We have no dispatch in RxR. When we need to pass new value to message stream (user clicked or so), we simply call:

userAdded$.next('A');

Now anything that observes the userAdded$ stream will get this message. With createPushMessageFunctions helper we can add syntactic sugar and create function userAdded() that will call .next itself so from the component you will calluserAdded('A') the same way as you can from Redux (if you bind the dispatch).

When you will create your message streams with help of createMessageStreams, you get both in one object by default.

Differences to mention

Redux action contains data. Redux action doesn't care where it will be consumed (reducer comes later...) and how it will get there (dispatch). That's why the action contains type property. It's kind of 'address' or 'signature'.

RxR stream on the other side defines the path of the data. Once the data are passed to userAdded$ stream, we know where we find them (actually when we observe this stream).

RxR stream therefore doesn't need the type to address the data (and usually the accompanying constants). You push your message into just one stream - the right one. Like "stream of user's click on ButtonX" or "user scrolls" or "data arrived from fetch"...