Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/lobor/redux-way

A small, simple and immutable model to manage data in your Redux store.
https://github.com/lobor/redux-way

Last synced: 7 days ago
JSON representation

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

Awesome Lists containing this project

README

        

# 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
```bash
npm install --save redux-way
```

## Usage
### Declare your model
```javascript
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
```javascript
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
```javascript
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 (


{counter}


Decrement
Incremente
Reset

)
}
}

// 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
```javascript
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);
```

```javascript
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