use-reduction
Version:
Simplify your reducer hooks
36 lines (35 loc) • 1.33 kB
JavaScript
import { useReducer, useMemo } from "react";
export default function useReduction(initialState, reducerMap, debug = false) {
const [state, dispatch] = useReducer(makeReducer(reducerMap), initialState);
const actions = useMemo(() => makeActions(reducerMap, dispatch, debug), [reducerMap]);
return [state, actions];
}
function makeReducer(reducerMap) {
return (state, action) => {
// if the dispatched action is valid and there's a matching reducer, use it
if (action && action.type && reducerMap[action.type]) {
return reducerMap[action.type](state, action);
}
else {
// always return state if the action has no reducer
return state;
}
};
}
function makeActions(reducerMap, dispatch, debug) {
const types = Object.keys(reducerMap);
return types.reduce((actions, type) => {
// if there isn't already an action with this type
if (!actions[type]) {
// dispatches action with type and payload when called
actions[type] = (payload) => {
const action = { type, payload };
dispatch(action);
// optionally log actions
if (debug)
console.log(action);
};
}
return actions;
}, {});
}