Created
December 26, 2017 04:59
-
-
Save luwes/569d8846b18e6a5406e1a218f5244b4d to your computer and use it in GitHub Desktop.
Experiment to add selectors to state as getters
This file contains hidden or 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
/** | |
The selectors would be a map e.g. | |
const selectors = { | |
ui: { | |
getDoubleBurgers: (state) => state.ui.burger + state.ui.burger | |
} | |
} | |
*/ | |
export default function proxySelectors(reducer, selectors) { | |
const map = generateSelectorsMap(selectors); | |
return (state = {}, action) => { | |
return setSelectors(state, reducer(state, action), map); | |
}; | |
} | |
function setSelectors(prevState, nextState, map) { | |
for (const path in map) { | |
const selectors = map[path]; | |
const slice = get(nextState, path); | |
if (slice) { | |
for (const name in selectors) { | |
const selector = selectors[name]; | |
if (!Object.getOwnPropertyDescriptor(slice, name)) { | |
Object.defineProperty(slice, name, { | |
get: () => selector(nextState) | |
}); | |
} | |
} | |
} | |
} | |
return nextState; | |
} | |
function get(obj, path, defaultValue) { | |
const keys = path.split('.'); | |
for (let i = 0; i < keys.length; i++) { | |
if (typeof obj === 'undefined') { | |
return defaultValue; | |
} | |
obj = obj[keys[i]]; | |
} | |
return obj; | |
} | |
function generateSelectorsMap(obj, keys = []) { | |
return Object.keys(obj).reduce((acc, key) => { | |
if (typeof obj[key] === 'function' && key !== 'default') { | |
const path = keys.join('.'); | |
const pathObj = acc[path] || {}; | |
pathObj[key] = obj[key]; | |
return Object.assign(acc, { [path]: pathObj }); | |
} | |
if (typeof obj[key] === 'object') { | |
return Object.assign(acc, generateSelectorsMap(obj[key], keys.concat(key))); | |
} | |
return acc; | |
}, {}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment