focus-redux-reducer v2.1.3
focus-redux-reducer
Redux reducer focused on productivity
Description
A Redux reducer usually is a function (function(Object state, Object action)) that updates the state and returns it. Usually the main body of that function is an ugly switch statement or even worse a series of an un-maintainable if...else statements.
const reducer = (state = {}, { type, payload, ...other }) => {
// An ugly switch
switch(type) {
case 'some_type':
return { ...state, myProperty: payload.someProperty };
case 'some_other_type':
return { ...state, myProperty: payload.someProperty };
.....
case 'some_other_type^N':
return { ...state, myProperty: payload.someProperty };
}
return state;
};So when reducers have many actions can easily become unmaintainable and confusing, this can be error prone, since developers must rely on es-linter to detect the mess.
Instead of a switch, a ReducerFactory class, maps the action.type with a class method, while it handles the state mutation using the returned object by the method.
Installation
npm install --save focus-redux-reducerBasic Usage
Create a new class that extends the ReducerFactory class and add your methods.
Methods can be mapped with a specific action.type by overriding the ReducerFactory.mapActionToMethod method or the method name could exact match an action.type. That method should return an object, containing all the properties that should be updated. Return empty object if there the state shouldn't be updated.
Another way to map an action.typewith a method is the of the the forType decorator
Also a special default method can be defined and will be called when the action.type matches none of the methods or the mapped methods of the class.
Example
MyReducer.js
import {ReducerFactory, State, Action } from 'focus-redux-reducer';
class MyReducer extends ReducerFactory {
// Mapping action types with instance methods
mapActionToMethod() {
return {
SOME_ACTION_NAME: this.mappedMethod
};
}
// Enter tour methods here
mappedMethod(payload) {
return this.updateStateProp('whatever', true);
}
fooMethod(payload, stuff) {
// It's not necessary to manualy update the state or make a copy of it.
// Whaterver the method return it will update the state.
return { foo: payload, ...stuff };
}
// The default function acts excactly as the `default` case of a `switch` block.
default(payload, { error }) {
// if no type matched and there is an error add return the error/
if (error !== undefined) {
return { error };
}
// Otherwise mutate nothing
return {};
}
}
const initialState = {
foo: null;
whatever: false
};
export default MyReducer.Create(initialState);App,js
import { createStore } from 'react-redux';
import MyReducer from './path-to/MyReducer';
const store = createStore(MyReducer);
store.dispatch({
type: 'SOME_ACTION_NAME',
payload: true
});
store.dispatch({
type: 'fooMethod',
payload: 'Hello World!'
stuff: {...}
});Decorator reference Experimental
@actionType(...type: string[])
NOTE: This requires decorators support so the compiler option experimentalDecorators in the tsconfig.json.
#tsconfig.js
{
"compilerOptions": {
"experimentalDecorators": true
....
}
}| argument | type | description |
|---|---|---|
| ...type | string[] | one or more type to bound with the method |
Example
import {ReducerFactory, State, Action, action } from 'focus-redux-reducer';
class MyReducer extends ReducerFactory {
@actionType(SOME_ACTION_TYPE, SOME_OTHE_ACTION_TYPE, ... , SOME_N_ACTION_TYPE)
someMethod({foo, bar}) {
return {
someStateParam: foo+bar
}
}
}Method reference
ReducerFactory.Create
| argument | type | default | description |
|---|---|---|---|
| initialState | object | {} | The initial state object |
| returns | |
|---|---|
| Reducer<S = object, A = Action> | A redux reducer function |
ReducerFactory.mapActionToMethod
| returns | |
|---|---|
| object<Action:callable(payload, ...args)> | An object with the mapped actions |
ReducerFactory.updateStateProp
| argument | type | default | description |
|---|---|---|---|
| property | string | A property name | |
| value | mixed | The value of that property |
| returns | |
|---|---|
| object | The new state |
ReducerFactory.updateState
| argument | type | default | description |
|---|---|---|---|
| newProps | object | An object with new properties name |
| returns | |
|---|---|
| object | The new state |
ReducerFactory.currentStateCopy
| returns | |
|---|---|
| object | A copy of the state |
ReducerFactory.removeStateProp
| argument | type | default | description |
|---|---|---|---|
| property | string | A property name to be removed |
| returns | |
|---|---|
| object | The new state |
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago