React类方法的this绑定:是否必须执行bind操作?
Let's start by looking at the two approaches you've shared, then break down the key questions you have.
Your arrow function approach:
class ExplainBindingsComponent extends Component { onClickMe() { console.log(this); } render() { return ( <button onClick={() => { this.onClickMe() }} type="button"> Click Me </button> ); } }
The constructor bind approach from your book:
class ExplainBindingsComponent extends Component { constructor() { super(); this.onClickMe = this.onClickMe.bind(this); } onClickMe() { console.log(this); } render() { return ( <button onClick={this.onClickMe} type="button"> Click Me </button> ); } }
Now, let's answer your questions one by one.
Do you need this.onClickMe = this.onClickMe.bind(this); with the arrow function approach?
Absolutely not. Here's why: Arrow functions don't have their own this context—they "inherit" the this value from the scope they're defined in (in this case, the render method's this, which is your component instance). So when you call this.onClickMe() inside the arrow function, this already points to your component, making the manual bind completely unnecessary.
Key differences between the two approaches
These two methods might seem to do the same thing on the surface, but there are important distinctions:
1. Timing of this binding
- Constructor bind: The binding happens once, when the component is first created. The
this.onClickMereference is updated to the bound function once, and that same function is reused for every render. - Arrow function wrapper: A brand new arrow function is created every single time the component renders. This new function captures the current component
thisand calls your method.
2. Performance considerations
Creating a new function on every render might sound trivial, but it can cause unnecessary re-renders if you pass this handler as a prop to a child component that uses React.memo or PureComponent. These components check for prop changes to decide whether to re-render—and a new function reference counts as a change, even if the underlying logic is identical.
The constructor bind approach avoids this issue entirely, since the function reference stays consistent across renders.
3. Handling event objects
If you need access to the React synthetic event (e.g., to prevent default behavior), there's a small difference in how you access it:
- Constructor bind: The event is automatically passed as the first argument to your method, so you can just define it like this:
onClickMe(e) { e.preventDefault(); console.log(this); } - Arrow function wrapper: You need to explicitly pass the event to your method if you want to use it:
<button onClick={(e) => this.onClickMe(e)} type="button">Click Me</button>
4. Reusability of the handler
If you need to use onClickMe in multiple places (e.g., passing it to another component or a utility function), the constructor bind approach gives you a single, stable function reference to reuse. The arrow function wrapper creates a new function each time, so you can't reuse that specific instance elsewhere.
Bonus: A cleaner middle ground (class property arrow functions)
You might also encounter this popular pattern, which eliminates the need for constructor boilerplate while keeping a stable function reference:
class ExplainBindingsComponent extends Component { // Define method as a class property arrow function onClickMe = () => { console.log(this); } render() { return ( <button onClick={this.onClickMe} type="button"> Click Me </button> ); } }
This uses class fields syntax to bind this to the component instance automatically, and the function is only created once when the component initializes.
Quick recommendations
- Use constructor bind or class property arrow functions when performance matters (e.g., frequently re-rendered components) or when you need to reuse the handler.
- Use the arrow function wrapper for simple, one-off cases—it's concise and avoids extra boilerplate.
内容的提问来源于stack exchange,提问作者user6427229

