redux-store-templates
Version:
Set of helpers to create useful and commonly used redux store patterns
187 lines (138 loc) • 4.26 kB
Markdown
# redux-store-templates
> **`redux-store-templates`** is a set of helpers that reduces boilerplate code needed to provide useful and commonly used patterns in designing store structure of redux based applicatons.
It's lightweight, dependency-free, can work with typescript and you can easily integrate it with your existing project as well as get rid of it.
***
## Example of usage
#### list
If you have the following action defined:
```js
{
type: '[PRODUCTS] fetching success',
payload: [
{ uuid: 'p1', name: 'product 1' },
{ uuid: 'p2', name: 'product 2' }
// ...
]
}
```
Then you can use `list` helper to create reducers this way:
```js
// products/reducers.js
import { combineReducers } from 'redux';
import { createReducer } from 'redux-store-templates/list';
export default combineReducers({
// ...
products: createReducer({
idName: 'uuid',
setOn: { type: '[PRODUCTS] fetching success' }
})
})
```
What will produce the following structure in the store:
```js
/*
...,
products: {
byId: {
'p1': { uuid: 'p1', name: 'product 1' },
'p2': { uuid: 'p2', name: 'product 2' }
...
},
ids: ['p1', 'p2', ...]
}
*/
```
Then you can create selectors standard way:
```js
// products/selectors.js
const selectProductsState = (state) => state.products;
/**
* @returns {Array<ProductDefinition>}
*/
export const selectAllProducts = (state) => {
const prouctsState = selectProductsState(state);
return productsState.ids.map(id => productsState.byId[id]);
}
/**
* @param {string} id - uuid of the product
*
* @returns {ProductDefinition | undefined}
*/
export const selectProductById = (state, id) => {
return selectProductsState(state).byId[id];
}
```
Or use provided helpers:
```js
// products/selectors.js
import { createSelectorAll, createSelectorById } from 'redux-store-templates/list';
const selectProductsState = (state) => state.products;
/**
* @returns {Array<ProductDefinition>}
*/
export const selectAllProducts = createSelectorAll({
selector: selectProductsState,
});
/**
* @param {string} id - uuid of the product
*
* @returns {ProductDefinition | undefined}
*/
export const selectProductById = createSelectorById({
selector: selectProductsState
});
```
You can handle more actions, like:
- _adding_,
- _updating_,
- _removing_
- _clearing_
as well as define your own - what may end up in configuration like this (real example):
```js
// products/reducers.js
import { combineReducers } from 'redux';
import { createReducer } from 'redux-store-templates/list';
export default combineReducers({
// ...
products: createReducer({
idName: 'uuid',
initial: [],
setOn: { type: '[PRODUCTS] fetching success' },
addOn: [
{ type: '[PRODUCTS] add multiple' },
{ type: '[PRODUCTS] add one', payloadPath: 'product' }
],
removeOn: { type: '[PRODUCTS] remove', payloadPath: 'ids' },
updateOn: { type: '[PRODUCTS] update' },
emptyOn: [
{ type: '[PRODUCTS] remove all' },
{ type: '[PRODUCTS] fetching started' },
{ type: '[PRODUCTS] fetching error' }
]
})
})
```
which replaces 100+ lines reducer - this is where **`redux-store-templates`** shines. :sparkles:
***
## More examples
- [counter](docs/examples.md#counter)
- [toggle](docs/examples.md#toggle)
- [value](docs/examples.md#value)
- [set-simple](docs/examples.md#set-simple)
- [task-simple](docs/examples.md#task-simple)
- [list](#list)
***
## Documentation
todo
***
## Installation
`npm install --save redux-store-templates`
or
`yarn add redux-store-templates`
**Caution**
By default **`redux-store-templates`** is written in ECMAScript 2018 language standard and it is recommended that you transpile it inside your project by your own (using ex. [@babel/preset-env](https://babeljs.io/docs/en/babel-preset-env)).
If you need older EcmaScript version, then import it from `es2015` directory:
```js
// import transpiled EcmaScript 2015 version
import { createReducer } from 'redux-store-templates/es2015/list';
```