Last active
May 5, 2016 16:06
-
-
Save Nilzor/a0a29ed60bc3e4d1543b80d5503cff11 to your computer and use it in GitHub Desktop.
A base class for reducers. Allows generating Redux Actions for functions by introspecting and naming the action from the class and function name.
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
/** | |
* A base class for generating Redux Actions for functions | |
* by introspecting and naming the action after the class and function name | |
*/ | |
export class AutoNamingReducer { | |
/** Generates and returns a Redux Action for the specified function. Function must reside in a class | |
* extending AutoNamingReducer | |
* @param func {function} A function reference | |
* @param params {object} An optional parameter object which will be spliced with the action object and passed | |
* to the action function when dispatched */ | |
actionFor(func, params) { | |
let className = Object.getPrototypeOf(this).constructor.name; | |
let actionObj = params || {}; | |
actionObj.type = this.createActionName(func.name); | |
return actionObj; | |
} | |
/** Call from reducer to invoke function from action. Returns new state if found, else same state */ | |
tryResolveAndReduce(state, action) { | |
let funcList = Object.keys(Object.getPrototypeOf(this)); | |
for (let func of funcList) { | |
if (this.createActionName(func) === action.type) { | |
console.log("AutoNamingReducer: matched " + func); | |
return this[func].call(this, state, action); | |
} | |
} | |
console.log("AutoNamingReducer: none matched " + action.type); | |
return state; | |
} | |
/** | |
* Creates an action name by concating the class name and function name | |
* @param funcName {string} The name of the function to create an action name for | |
* @return {string} The action name | |
*/ | |
createActionName(funcName) { | |
let className = Object.getPrototypeOf(this).constructor.name; | |
return className + "." + funcName; | |
} | |
} |
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
// How a reducer would be implemented with AutoNamingReducer | |
// -No magic strings, no switch case - just functions | |
class todoReducer extends AutoNamingReducer { | |
reduce(state = [], action = null) { | |
return this.tryResolveAndReduce(state, action); | |
} | |
addTodo(state, action) { | |
return { | |
id: action.id, | |
text: action.text, | |
completed: false | |
} | |
} | |
toggleTodo(state, action) { | |
if (state.id !== action.id) { | |
return state | |
} | |
return Object.assign({}, state, { | |
completed: !state.completed | |
}) | |
} | |
} | |
let reducer = new todoRedcuer(); | |
export default reducer.tryResolveAndReduce; | |
// Example usage | |
dispatch(reducer.actionFor(reducer.toggleTodo, {id: 2})); |
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
// How a reducer would be implemented with the old pattern | |
const ADD_TODO = 'ADD_TODO'; | |
const TOGGLE_TODO = 'TOGGLE_TODO'; | |
const todo = (state, action) => { | |
switch (action.type) { | |
case ADD_TODO: | |
return { | |
id: action.id, | |
text: action.text, | |
completed: false | |
} | |
case TOGGLE_TODO: | |
if (state.id !== action.id) { | |
return state | |
} | |
return Object.assign({}, state, { | |
completed: !state.completed | |
}) | |
default: | |
return state | |
} | |
} | |
// Example usage | |
dispatch({type: TOGGLE_TODO, id: 4}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment