Skip to content

Instantly share code, notes, and snippets.

@mcspud
Created November 13, 2018 02:11
Show Gist options
  • Save mcspud/9d75f4130799cce535e413826a2de9bc to your computer and use it in GitHub Desktop.
Save mcspud/9d75f4130799cce535e413826a2de9bc to your computer and use it in GitHub Desktop.
/*
Ok why the hell do we want this function?
The secret lies in understanding how Reselect and Immutable js work, and utilising equality comparators
correctly. Remember folks, understand your tools.
Reselect:
--------------
The way a reselect.createSelector works is as follows:
Take N number of comparator functions, and check if the current value is equal to the previous value
- If the values havent changed, return the previously memoized version
- If the values HAVE changed, take the comparison function inputs as values, pass them to your
expensiveComputation function, memoize the result and return it back
The type signature and an example 1 arity function are shown below:
lifeCycleSelector : a -> Bool -> b
lifeCycleSelector = createSelector(
state => state.getIn(['files', 'lifecycle']),
lifecycle => lifecycle.toJS()
);
Now, to do the comparison reselect uses a simple equality operator === , which in JavaScript means that
anything besides primitives like Integer, String etc ARE COMPARED BY REFERENCE. Ignoring the structural
sharing of memory of current JSv8 engines, this essentially means that the for complex objects, or current
results of functions, the comparison is always ID based on memory location, not structural values. Check
this yourself in the console: {a: 1} === {a: 1}
Immutable:
--------------
Immutable is a freaking beast of a library, and if you're interested in sequence-based programming it is a
great way to learn how to think across collections. Its key feature lives in its name - ie Immutability.
This means that a when it does some sort of processing, we get access to a brand new tree of objects,
meaning that any reference holds are GONE. Immutable does however ship with a lovely hashing system it
automatically applies to all collections:
https://facebook.github.io/immutable-js/docs/#/Collection.Indexed/hashCode
That this means is that each collection ImmutableJS generates has a lovely, predictable equality hash
provided along with it. Predictable means it is not cryptographically secure, but also pure by
definition. When comparing collection results, we then only need to compare hash codes, instead of doing
deep comparators across the collection.
Usage:
--------------
Now that we know that ImmutableJS always gives us a new thing so reference equality will not work, but that
it also gives us predictable collection hashes, we need to combine these two properties to rewrite the way
that Reselect does its comparison.
Remember from above, Reselect.createSelector uses simple equality === to check for differences. We need to
tell it instead to use Immutables version of that at the surface level-API - Immutable.is:
https://facebook.github.io/immutable-js/docs/#/is
We import the default memoization operation, run the cheap equality comparators, do the expensive
computations including converting to natural javascript objects, and dispatching it to props.
*/
import * as Immutable from 'immutable';
import {createSelectorCreator, defaultMemoize} from 'reselect';
export default createSelectorCreator(defaultMemoize, Immutable.is);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment