redux-easy-models
Easily define your models using standard redux libraries (redux, redux-actions, redux-thunk).
(This package is still experimental)
Installation
npm install --save redux-easy-models
Rationale
In a plain vanilla redux implementation with the help of some helper libraries
like redux-actions
and redux-thunk
you might end up with something like this:
actions/timer.js
const start = //... more action creators here. start ;
reducers/timer.js
;const startReducer = ;
Later in you containers or components you'd have to dispatch actions like this:
;//...;
While this decouples the code and keeps things simple, the amount of boilerplate
and disconnection between actions and reducers can feel painful at times. With
redux-easy-models
you could achieve the same with the following code:
models/timer.js
;
Notice how all the code for the "timer" model is in a single file. When you want to dispatch your actions, all you have to do is:
;//...modelapistart;
This will automatically dispatch standard actions with standar action types. In this case the action would look like this:
{
type: "TIMER_START"
}
redux-easy-models
supports defining actions with sync and async functions, and
chaining multiple actions.
Demo
For a working demo you can go here.
Usage
;
Define your models using a single configuration object:
const timer = // the name of the model. we will use this name to force // a convention where every action will have a type with // the name as the prefix. Can be used to combine reducers // as well. ie: // const reducers = combineReducers({ // [timerModel.name]: timerModel.reducer // }); name: 'timer' // reducer's initial state. initialState: started: false count: 0 timerId: null // actions can either be strings or named functions. actions: // in case of strings, action creators will be generated // with redux-actions. the name of the model will be used // as a prefix as well, ie: // let actionCreator = createAction('TIMER_INCREASE'); 'increase' 'clear' // functions should be named and will automatically // generate two actions, one when the execution starts, // one in case of success or failure. // action types will follow an upper snake convention with // the name as the prefix, ie: // function doSomething() {... // will be translated to an action type of: // TIMER_DO_SOMETHING_START // TIMER_DO_SOMETHING_SUCCESS // TIMER_DO_SOMETHING_FAIL { thisclear; return ; } { return thistimerId; } { let timerId = this; ; } // functions can be async and/or return a promise, // and the right success/fail action will be generated based // on whether the promise is resolved/rejected. // in case the function is not async and is sync, // start/success/fail actions will also be generated, and // the execution will be wrapped in a try/catch statement { await ; thisstart; } // reducers can be defined for actions generated by this model. // no need to use prefix, and sufix in the case of 'Success' is // options, so in the following list 'start' and 'startSuccess' // are pretty much the same. reducers: { return Object; } { return Object; } // remember that actions generated with strings in the 'actions' // definition will not generate start/success/fail actions, so // in this case, 'increaseSuccess' and increaseFail will not work and // will never be called. { return Object; } { return Object; } ; // helper function to demonstrate async { return ;} // export your model ;
Once you have your model, you plug it in your redux store (redux-thunk is required).
;;;//models;;const reducers = ; const logger = ;const store = ; // make sure you init your model with the store!!timerModel;
NOTICE: how the model is initialized right after the redux store is created.
Now you can consume your model from your containers or components.
;; const HomeContainer = HomeComponent; ;
Actions wills be generated as usual:
Helpers
There are two helper methods in case you have more than one model in your application.
combineModelReducers & initModels
You can arrange your models in an array or an object:
;;; ; // could be export [ user, entries, comments]
;;; // import the new helper functions //models; // combine all of the ReduxModel reducersconst reducers = ; const logger = ;const store = ; // init all the ReduxModels;
Credits
Thanks to Dan for his contributions of helper methods!