Skip to content

Instantly share code, notes, and snippets.

@jabney
Last active January 22, 2020 20:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jabney/fe54d7490e10575ab6277fe433009e0e to your computer and use it in GitHub Desktop.
Save jabney/fe54d7490e10575ab6277fe433009e0e to your computer and use it in GitHub Desktop.
micro-reselect: memoize a function based on the state passed to it (mimics reselect npm module)
/**
* Implement a simplified createSelector function mimicking the reselect module.
*
* Memoizes the result of a function called with a state object as its argument.
* The given function is only called when state values change.
*/
/**
* A resolver returns a value from a state object (key/value pairs).
*
* @typedef {(state: any, props?: any) => any} Resolver
*/
/**
* @param {Resolver | Resolver[]} resolvers
* @param {(state: any) => any} fn
*
* @returns {(state: any, props?: any) => any}
*/
const createSelector = (resolvers, fn) => {
let resolved = []
let cache = null
// Convert resolvers to an array.
const res = Array.isArray(resolvers) ? resolvers : [resolvers]
/**
* @type {(state: any, props?: any) => any}
*/
const selector = (state, props) => {
// Get the current state's values.
const values = res.map(r => r(state, props))
// Determine if any of the values have changed.
const changed = values.some((value, i) => value !== resolved[i])
if (changed) {
// Update resolved state values and the cache.
resolved = values
cache = fn.apply(null, values)
}
return cache
}
return selector
}
export default createSelector
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment