yarn add @lsmoura/create-reducer
This helper lets the user creates simple or nested reducers.
initialState is an object or value that represents the initial state.
handlers is an object that has the format ACTION_NAME: reducer
or key: handlers
.
Some examples:
const handlers = {
'ADD': (state, action) => (state + 1),
'SUBTRACT': (state, action) => (state - 1),
};
or
const handlers = {
'todo': {
'ADD_TODO': (state, action) => state.concat(action.value),
},
'counter': {
'ADD': (state, action) => (state + 1),
'SUBTRACT': (state, action) => (state - 1),
},
};
or even
const counterHandlers = {
'ADD': (state, action) => (state + 1),
'SUBTRACT': (state, action) => (state - 1),
};
const handlers = {
'todo': {
'ADD_TODO': (state, action) => state.concat(action.value),
},
'counter': counterHandlers,
'counter2': counterHandlers,
};
nested parameters will have their state extracted from the original state and the result will be assigned back to the key.
you can nest parameters as much as you like:
const counterHandlers = {
'ADD': (state, action) => (state + 1),
'SUBTRACT': (state, action) => (state - 1),
};
const handlers = {
'deeply': {
'nested': {
'counter': counterHandlers,
},
},
};
the createReducer function will ignore any handler key that starts with $
.
It will also send a default state for your reducer function if you provide
a key of $defaultState
and there is no state value assigned to the key you
provide:
const handlers = {
'$defaultState': 0,
'ADD': (state, action) => (state + 1),
'SUBTRACT': (state, action) => (state - 1),
};
wrapper is an optional parameter. it must be a function that will wrap your
reducer function. It's recommended to use objectActionHandler
as this
parameter to help reduce the amount of "spreading" or
"Assigning"
on your reducers.
This is a wrapper helper that assigns the returned state to the existing one, like so:
function(reducer, state, action) {
const reducerResult = reducer(state, action);
return Object.assign({}, state, reducerResult);
}
Every example assumes that the module is imported in the following way:
import import createReducer, { objectActionHandler } from '@lsmoura/create-reducer';
const reducer = createReducer(
0,
{
'ADD': (state, action) => (state + 1),
'SUBTRACT': (state) => (state - 1),
},
objectActionHandler
);
const reducer = createReducer(
undefined,
{
'$defaultState': 0,
'ADD': (state, action) => (state + 1),
'SUBTRACT': (state) => (state - 1),
},
objectActionHandler
);
const counterHandlers = {
'$defaultState': 0,
'ADD': (state, action) => (state + 1),
'SUBTRACT': (state) => (state - 1),
};
const reducer = createReducer(
{},
{
counter: counterHandlers,
counter2: counterHandlers,
},
objectActionHandler
);
const handleAddSubtract = {
'$defaultState': 0,
'ADD': (state, action) => (state + 1),
'SUBTRACT': (state) => (state - 1),
};
const handleAddTodo = {
'$defaultState': [],
'TODO_INSERT': (state, action) => Array.concat(state, action.value),
};
const reducer = createReducer(
defaultState,
{
'ADD': (state, action) => ({ action_count: 1 + (state.action_count || 0) }),
counter: handleAddSubtract,
counter2: handleAddSubtract,
nesting_todos: {
inner_object: {
todos: handleAddTodo,
},
},
nested: nestedReducer.handlers,
},
objectActionHandler
);