Created
November 6, 2017 17:55
-
-
Save m3g4p0p/a1dc51fa720746b093a77282816813f1 to your computer and use it in GitHub Desktop.
Bind functions to instances in a way that maintains strict equality when done multiple times
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
const bindings = new WeakMap() | |
const getFns = context => { | |
if (!bindings.has(context)) { | |
bindings.set(context, {}) | |
} | |
return bindings.get(context) | |
} | |
const bindOnce = (fn, context) => { | |
const fns = getFns(context) | |
const key = fn.toString() | |
if (!bindings[key]) { | |
bindings[key] = fn.bind(context) | |
} | |
return bindings[key] | |
} | |
export default bindOnce |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why?
In React, it's bad to declare functions inside a
render()
method and pass them down as props, as pure components just check for equality of the props received, and two sepearate function are never equal even if they do the same thing on the same instance.A common solution to this problem is to do bind the methods to
this
in the constructor, which is of course a bit of a hassle. Also you can't conveniently write arrow functions inline in the render mathod, which would be more readable in some cases.So another possible solution would be a custom bind function as this one, which associates functions with instances in a weak map, and looks up existing bindings by their stringified versions.
Usage
Inspired by
reflective-bind
:https://github.com/lencioni/reflective-bind
https://flexport.engineering/ending-the-debate-on-inline-functions-in-react-8c03fabd144