In the 3.x.x this rule was turned on. Reasoning is clear and makes a perfect sense. But this commit doesn't make sense to me. Why refs and arrow functions are allowed, while bind is not? New arrow functions are being created on each re-render and they !== to each other, so what's the point of this rule with this change?
Found a PR. But these 2 threads are confusing.
@alexfedoseev .bind is incredibly slow, much slower than using an arrow function.
@ljharb Got it :+1:
Just curious, what about equality check? Since on each re-render we create new function, then all components with such props will be flushed to the DOM. And DOM update is the one of the most expensive operation. (Correct me if I'm wrong in some point).
That was my previous understanding, but since React has a default shouldComponentUpdate implementation of return true, and since most event handlers are added to a global delegation pool and not attached directly to DOM elements, this isn't actually a performance concern even though it seems like it should be.
I see then, thanks for explanation!
Given this, is the following guidance still relevant?
Bind event handlers for the render method in the constructor.
Why? A bind call in the render path creates a brand new function on every single render.
If not, it should be removed for the sake of clarity.
It's still a true statement that can indeed impact performance - just not enough to warrant linter enforcement.
I'm still very confused by this. What is the recommended best practice? Should I keep using stateless functions when I have callbacks and use arrow functions in the JSX, or should I use classes and bind in the constructor?
@dalexander01 either way is good. SFCs are better than stateful components, but use whichever approach fits the component type you have.
All else being the same, if the onClick handler needs access to a prop value, is it preferable to bind the handler in a stateless component (onClick={() => props.onSelect(props.eventKey)}) or to use a bound method in a stateful component?
imo, a stateless component is so much better than a stateful one, that any potential tiny performance difference (and I suspect there's none) is absolutely worth it - iow, stateless.
Okay, so in other words, the rule is: when using a stateful component, bind handlers in the constructor, but prefer using a stateless component with arrow functions for handlers in render?
Well stated, yes :-)
What about breaking equality checks in child SCU hooks?
If that's a concern, then certainly the component needs to be stateful, because you're maintaining the state of the bound function.
I guess the question is, should it be a concern or are we just splitting hairs here?
I don't think it should be a concern, but if it worries you, ¯_(ツ)_/¯
cc @jquense
The performance benefit you get from skipping re-rendering on an entire tree should far outweigh any benefit you get from bind vs closures.
Now I'm confused again :(
Most helpful comment
Okay, so in other words, the rule is: when using a stateful component, bind handlers in the constructor, but prefer using a stateless component with arrow functions for handlers in
render?