JSX中this对象绑定问题

箭头函数内自动继承了上下文语义中的this对象;
在点引用直接调用中,引用对象this指针也会自动传递到被引用方法中。但点引用、引用调用和箭头函数同时出现时,容易混淆,我们把合法的写法做一个总结。我们先来看一段计时器示例:我们把index.html放在/public文件夹下,把index.js,app.js,及全局样式表index.css放在/source中:

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
class Counter extends React.Component
{
constructor(props)
{
super(props);
this.state={count: 0};//状态对象初始化状态
}
()=>Count()
{
this.setState({count: this.state.count+1});
}
render()
{
return (<div><h2>The Count is {this.state.count}</h2><p><button onClick={this.Count}>+1</button></p></div>);
}
}
class Clocker extends React.Component
{
constructor(props)
{
super(props);//调用React.Component构造函数,此后this建立
this.state={date:new Date()};//状态对象初始化状态,仅能出现在状态函数中
}
componentDidMount()
{
this.timerId=setInterval(()=>this.tick(),1000);
//默认单位为毫秒,即每隔1s立即调用this.tick方法
}
componentWillUnmount()
{
clearInterval(this.timerId);
}
tick()
{
this.setState({date:new Date()});
}
render()
{
return (<div><p>The time is {this.state.date.toLocaleTimeString()}</p></div>);
}
}
const test=ReactDOM.createRoot(document.getElementById("test"));
const root=ReactDOM.createRoot(document.getElementById("root"));
root.render(<Clocker/>);
test.render(<Counter/>);

为什么Clocker类方法tick()是普通函数,而Counter类方法Count必须是箭头函数呢?

写法1:
<button onClick={this.Counter}>,Counter()必须为箭头函数。这是一个引用调用,在执行主函数React.render()时,由于只是取出Counter函数,不会发生死循环。
写法2:
<button onClick={()=>this.Counter()}>这是一个匿名箭头函数,内部采用直接引用,因此在点击时不会出现“裸引用”,Counter既可以是普通函数,也可以是箭头函数。render继承当前实例的this,箭头函数内部继承render的this,Counter函数内部继承引用对象,即箭头函数里的this,不会出现undefined。
错误写法:<button onClick={this.Counter()},这种情况下,编译时会出现render()->Counter()->setState()->render()死循环
错误写法:<button onClick={()=>this.Count},这种情况下,不会死循环,但点击无反应,因为箭头函数内部是引用调用。
错误写法:<button onCLick={this.Count},且Count为普通函数。这种情况下,不会死循环,但点击时对“已取出”的方法Count进行“裸引用”,按钮无反应。


JSX中this对象绑定问题
http://example.com/2025/08/16/day1/
作者
Androw Smith
发布于
2025年8月16日
许可协议