A small, simple and immutable model to manage data in your Redux store.

Motivation

After multiple project with react and redux, the file structure begin unmaintainable, constants on one side, reducers on another. I tried to put everything in a file but I end up with a large file. So I created for my needs, a bookstore allowing me to have maintainable and clear code I was inspired by react-redux and react-ORM

Installation

npm install --save redux-way

Usage

Declare your model

import { Model } from ' redux-way ' ; export const INCREMENT = ' INCREMENT ' ; export const DECREMENT = ' DECREMENT ' ; export const RESET = ' RESET ' ; export default class CounterModel extends Model { static modelName = ' counter ' ; static state = 0 ; static actions = { increment : ( ) => ( { type : INCREMENT } ) , decrement : ( ) => ( { type : DECREMENT } ) , reset : ( ) => ( { type : RESET } ) } ; reducer = { [ INCREMENT ] : ( state , action , model ) => { model . update ( state + 1 ) } , [ DECREMENT ] : ( state , action , model ) => { model . update ( state - 1 ) } , [ RESET ] : ( state , action , model ) => { model . update ( 0 ) } } ; }

Register your model and create store

import { createStore } from ' redux ' ; import { Register } from ' redux-way ' ; import { CounterModel } from ' ./model ' ; const register = new Register ( ) ; register . register ( CounterModel ) ; const store = createStore ( createReducer ( register ) ) ;

Connect your composant

import React from ' react ' ; import { CounterModel } from ' ./models ' ; import { connect } from ' redux-way ' ; export class Counter extends React . Component { render ( ) { const { counter , decrement , increment , reset } = this . props ; return ( < div > { counter } < br / > < button onClick = { decrement } > Decrement < / button > < button onClick = { increment } > Incremente < / button > < button onClick = { reset } > Reset < / button > < / div > ) } } const mapStateToProps = ( state ) => { return { counter : state . counter } } const mapDispatchToProps = { increment : CounterModel . actions . increment , decrement : CounterModel . actions . decrement , reset : CounterModel . actions . reset , } export default connect ( mapStateToProps , mapDispatchToProps ) ( Counter )

Use redux-saga

import { createStore } from ' redux ' ; import { Register } from ' redux-way ' ; import createSagaMiddleware from ' redux-saga ' import { CounterModel } from ' ./model ' ; const sagaMiddleware = createSagaMiddleware ( ) const register = new Register ( ) ; register . register ( CounterModel ) ; const store = createStore ( createReducer ( register ) ) ; register . sagaMiddleware ( sagaMiddleware ) ;

import { Model } from ' redux-way ' ; import { delay } from ' redux-saga ' import { put , takeEvery } from ' redux-saga/effects ' export const INCREMENT = ' INCREMENT ' ; export const ASYNC_INCREMENT = ' ASYNC_INCREMENT ' ; export const DECREMENT = ' DECREMENT ' ; export const RESET = ' RESET ' ; export default class CounterModel extends Model { static modelName = ' counter ' ; static state = 0 ; static actions = { increment : ( ) => ( { type : INCREMENT } ) , asyncIncrement : ( ) => ( { type : ASYNC_INCREMENT } ) , decrement : ( ) => ( { type : DECREMENT } ) , reset : ( ) => ( { type : RESET } ) } ; run = function * ( ) { yield takeEvery ( ASYNC_INCREMENT , this . changeName ) } changeName = function * ( ) { yield delay ( 1000 ) ; yield put ( { type : INCREMENT } ) } reducer = { [ INCREMENT ] : ( state , action , model ) => { model . update ( state + 1 ) } , [ DECREMENT ] : ( state , action , model ) => { model . update ( state - 1 ) } , [ RESET ] : ( state , action , model ) => { model . update ( 0 ) } } ; }

Api

Model