Last active
February 20, 2020 23:54
-
-
Save sebbdk/04bbee348b38ee357b4043e7aace9a9e to your computer and use it in GitHub Desktop.
List redux reducer creator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This can be used to bootsrap making reducers that only have to manage an array of data. | |
// crud-lib.js | |
import nanoid from 'nanoid'; | |
export function createActionTypes(reducerAlias) { | |
return { | |
add: Symbol(`CUD add in ${reducerAlias}`), | |
remove: Symbol(`CUD remove in ${reducerAlias}`), | |
update: Symbol(`CUD remove in ${reducerAlias}`), | |
replace: Symbol(`CUD replace in ${reducerAlias}`) | |
}; | |
} | |
export function createDispatchers(actionTypes) { | |
return { | |
add: (item) => ({ type: actionTypes.add, item }), | |
remove: (item) => ({ type: actionTypes.remove, item }), | |
update: (item) => ({ type: actionTypes.update, item }), | |
replace: (item) => ({ type: actionTypes.replace, item }), | |
} | |
} | |
export function createActions(types, key = 'id') { | |
return { | |
[types.add]: (state, action) => ([ ...state, { id: nanoid(), ...action.item}]), | |
[types.remove]: (state, action) => state.filter(i => i[key] !== action.item[key]), | |
[types.update]: (state, action) => state.map(i => { | |
return i[key] === action.item[key] | |
? { ...i, ...action.item } | |
: i; | |
}), | |
[types.replace]: (state, action) => state.map(i => { | |
return i[key] === action.item[key] | |
? action.item | |
: i; | |
}) | |
} | |
} | |
// @todo, https://github.com/anywhichway/nano-memoize | |
export function createSelectors(statePath) { | |
let mem; | |
let preRes; | |
return { | |
find: (conditions) => (state) => { | |
if(mem === state) return preRes; | |
const subState = statePath.reduce((acc, curr) => acc[curr], state) | |
const res = subState.find(i => { | |
return Object.keys(conditions).reduce((match, key) => { | |
return i[key] === conditions[key]; | |
}, true); | |
}); | |
mem = state; | |
preRes = res; | |
return res || []; | |
} | |
} | |
} | |
export function createReducer(reducerAlias, {types, actions, key = 'id', initialState} = {}) { | |
if(!types) types = createActionTypes(reducerAlias); | |
if(!actions) actions = createActions(types, key); | |
if(!initialState) initialState = []; | |
return (state = initialState, action) => { | |
return actions[action.type] | |
? actions[action.type](state, action) | |
: state; | |
}; | |
} | |
// my-reducer.js | |
export const types = createActionTypes('content'); | |
export const actions = createDispatchers(types); | |
export const selectors = createSelectors(['content']) | |
export const contents = createReducer('content', { initialState, types }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment