🤪 simple rxjs integration for redux
npm i redux-rx-middleware
or
yarn add redux-rx-middleware
it supports rxjs 6.x versions
redux
because it's middleware for reduxrxjs
because it's rx middlewaretslib
forcls
andesm
packages it uses three shaking to decrease bundle size@types/redux-actions
for support FSA for redux
add middleware
import { rxMiddleware } from "redux-rx-middleware";
dispatch action with observable stream
import { from } from "rxjs";
import { OBSERVABLE_API, ObservableAction } from "redux-rx-middleware";
export function observableAction(): ObservableAction<number> {
return {
type: "ACTION_TYPE",
meta: {
[OBSERVABLE_API]: {
stream: from([1, 2, 3]),
},
},
};
}
For the official integration (from core contributors) with RxJS and Redux, please take a look at redux-observable
This is a simple middleware like redux-promise which adds support Rx.Observable for the actions.
first of all, redux-observable uses Epics to describe async actions in redux.
Epic is a function which takes a stream of actions and returns a stream of actions. Actions in, actions out.
so you can feel free to manage your stream of actions with Epics, but this is an additional entity, it brings specials api on top of redux. also you can not dispatch multiple actions - more detils here
this redux-rx-middleware provides 2 things:
- if has
meta
has a key with an Observable stream, it will subscribe to this stream - it will handle one Observable action to many simple actions with a different state of execution. For example, incoming action:
{
type: "ACTION_TYPE",
meta: {
["@api/OBSERVABLE_API"]: {
stream: from([1, 2, 3]),
},
},
}
outgoing actions will be
{
type: "ACTION_TYPE",
meta: {
["@api/OBSERVABLE_API"]: {
sequence: "start",
},
},
}
------------------------------
|
|
V
{
type: "ACTION_TYPE",
payload: 1,
meta: {
["@api/OBSERVABLE_API"]: {
sequence: "next",
},
},
}
------------------------------
|
|
V
{
type: "ACTION_TYPE",
payload: 2,
meta: {
["@api/OBSERVABLE_API"]: {
sequence: "next",
},
},
}
------------------------------
|
|
V
{
type: "ACTION_TYPE",
payload: 3,
meta: {
["@api/OBSERVABLE_API"]: {
sequence: "next",
},
},
}
------------------------------
|
|
V
{
type: "ACTION_TYPE",
meta: {
["@api/OBSERVABLE_API"]: {
sequence: "complete",
},
},
}
Why does it mapped one async action to many sync actions? In general overview the async action can has one type but different states:
({type: "GET_USERS", sequence: "start" })
👇🏼
({type: "GET_USERS", sequence: "done" })
👇🏼
({type: "GET_USERS", sequence: "error" })
or as usual in redux applications, different types around the one async action:
({type: "GET_USERS" })
👇🏼
({type: "GET_USERS_DONE"})
👇🏼
({type: "GET_USERS_ERROR"})
The benefit of the first flow that in both cases you need to handle this actions in reducer by sequence state or by action type, but you can delegate the creation of the state actions to middleware, don't create additional action by yourself. The main goal of this simple middleware that one async action (with Rx API) has different states and you can just handle it in your reducer.