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;;; const initialState = {}; const Store = ;
A store instance has following signiture and it can be accessed any time any place it is importat. Yet it is not encouraged to miss use it ;)
//store interface exampleinterface StoreInterface state: Subject<State>; select: ...selectors: string | Selector: State ; void; subscribe: next?: void error?: void complete?: void Subscription; State;
Middlewares
There are nearly all neccessary middlewares available like reduxDevTools integration and Effects (for side effects). To insert middlewares there is a special function caled applyMiddlere (see above). Besides if you like to create your own middleware you may refer to following example. (LoggerMiddleware has the bare minimum middleware signiture)
//store.js;;; const initialState = {}; const LoggerMiddeleware = { console; return ;} const Store = ;
Actions
An action can be any javascript object wich has a type attribute. In the example below object factories used for the sake of example itself. A class or simple object will do the trick.
// actions.jsconst GET_TODO = 'GET_TODO'; { return type: GET_TODO }
Consuming the actions dispatch function of store should be used.
; Store;
Effects
Effects are basically is the same thing with redux-observable. This small middleware is provided within the library by taking in to consideration that most of the apps has side effects. And to have this functionality without another library dependency will reduce the dependency overhead. Effects requires a helper function/decorator which is Effect/@Effect (no worries it is also included in te library :)). To combine Store and Effects RxDx provides a middleware called effectsMiddleware which need to be passed into createStore
;;;; { thisonGetToDos = _actions$ ; thisonAddToDo = _actions$ ; thisonUpdateToDo = _actions$ ; } const todoEffects = todoService actions$;
if your development environment supports decorators an effect can be used as follows.
@thisonGetToDos = _actions$ ;
Additonally actions$ is an onbservable of action which mean it is possible to use all RxJs tappable functions or anything related with observable streams as long as the stream mapped to an action. Basicly it is up to your creativity ;)
Selectors
In any react component you will need to subscribe to relevant porion of State so you may do it in two ways. One is using the key of state (can be nested, yeaaay!).
/** * Assuming the state object in the store as follows * { * todos: { * todoList: ['todo1', 'todo2'] * } * } */; Store ;
Or the second one is using a selector which is created by createSlector function which is more performant thanks to built in momoization. (Incase you have to do complex calculation over state).
// todo.selectors.js; const combinedStateSelector = statetodos;const todoListStateSelector = ;
Then the code for selection of a too list can be re written as follows
;; Store ;
Reducers
Like redux for reducers there is a combineReducers function and it can be nested so it is possible to create well structured state objects. As it can be guessed a reducer written for reduc can be used as is in RxDx also.
// todo.reducer.js { } { } const todoReducer = ; //store.js;; const initialState = {}; const Store = ;
Connect to React Components
So far there were no connection to a react component and can be used independent from react. But what's the point if we are not using it in react? Since react has its own rendering mechanism and internal states etc. there is a need for a connecter smart enough stich the RxDx into react lifecycle and this is called connect
;;;;; const ToDoPage = { return <div className="todo-page"> todos ? todos : undefined </div> } const toProps = todos: Store;const ToDoEnhanced = ToDoPage;
If your environment allows you to use decorators it is possible to use connect as a decorator
const toProps = todos: Store; @ extentds Component { const todos = thisprops; return <div className="todo-page"> todos ? todos : undefined </div> }
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.