redux-store-templates
v1.1.0
Published
Set of helpers to create useful and commonly used redux store patterns
Downloads
36
Maintainers
Readme
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:
{
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:
// 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:
/*
...,
products: {
byId: {
'p1': { uuid: 'p1', name: 'product 1' },
'p2': { uuid: 'p2', name: 'product 2' }
...
},
ids: ['p1', 'p2', ...]
}
*/
Then you can create selectors standard way:
// 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:
// 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):
// 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
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).
If you need older EcmaScript version, then import it from es2015
directory:
// import transpiled EcmaScript 2015 version
import { createReducer } from 'redux-store-templates/es2015/list';