redux-way

0.2.5 • Public • Published

redux-way

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 {
    // Used to resolve all related store 
    static modelName = 'counter';
 
    // Initial state
    static state = 0;
 
    // Differents actions related to the model
    static actions = {
        increment: () => ({type: INCREMENT}),
        decrement: () => ({type: DECREMENT}),
        reset: () => ({type: RESET})
    };
 
    // Reducer linked by constants
    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 your models
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>
        )
    }
}
 
// Same api as react-redux
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 your models
register.register(CounterModel);
 
const store = createStore(createReducer(register));
 
// register sagaMiddleware, launch after store has been created
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 {
    // Used to resolve all related store 
    static modelName = 'counter';
 
    // Initial state
    static state = 0;
 
    // Differents actions related to the model
    static actions = {
        increment: () => ({type: INCREMENT}),
        asyncIncrement: () => ({type: ASYNC_INCREMENT}),
        decrement: () => ({type: DECREMENT}),
        reset: () => ({type: RESET})
    };
 
    // launch by sagaMiddleware.run
    run = function* () {
        yield takeEvery(ASYNC_INCREMENT, this.changeName)
    }
 
    changeName = function* () {
        yield delay(1000);
        yield put({type: INCREMENT})
    }
 
    // Reducer linked by constants
    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

  • update(mergeObj): update the state by merging mergeObj. Returns undefined

Package Sidebar

Install

npm i redux-way

Weekly Downloads

11

Version

0.2.5

License

MIT

Last publish

Collaborators

  • lobor