ReactJS虚拟DOM效应带来的一则副作用探索

时间:2021-06-13 12:26:15

疑问

https://github.com/ruanyf/react-demos/blob/master/demo08/index.html

在如下代码中的 18 行, 需要将本类中的 方法,进行绑定到this,即当前组件,但是render函数就不需要,为什么呢?

this.handleClick = this.handleClick.bind(this)
 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="../build/react.development.js"></script>
<script src="../build/react-dom.development.js"></script>
<script src="../build/babel.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
class LikeButton extends React.Component {
constructor(props) {
super(props)
this.state = {
liked: false
}
this.handleClick = this.handleClick.bind(this)
}
handleClick(event) {
this.setState({ liked: !this.state.liked });
}
render() {
var text = this.state.liked ? 'like' : 'haven\'t liked';
return (
<p onClick={this.handleClick}>
You {text} this. Click to toggle.
</p>
);
}
} ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
</script>
</body>
</html>

实验

将上行例子中的18行注释后, 运行效果。

 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="../build/react.development.js"></script>
<script src="../build/react-dom.development.js"></script>
<script src="../build/babel.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
class LikeButton extends React.Component {
constructor(props) {
super(props)
this.state = {
liked: false
}
//this.handleClick = this.handleClick.bind(this)
}
handleClick(event) {
this.setState({ liked: !this.state.liked });
}
render() {
var text = this.state.liked ? 'like' : 'haven\'t liked';
return (
<p onClick={this.handleClick}>
You {text} this. Click to toggle.
</p>
);
}
} ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
</script>
</body>
</html>

浏览器运行结果,控制台有报错:

ReactJS虚拟DOM效应带来的一则副作用探索

思考

本来以为是 babel把es6翻译成es5特殊要求导致。

最后找到问题根因是,事件处理handler引入的特殊要求, 因为ReactJS使用了 virtual DOM, 生成的组件是虚拟的,并不是页面上真实显示的控件。

对于页面上真实存在的控件, 在事件处理的handler中, 使用this表示控件本身。

例如:

http://www.w3school.com.cn/tiy/t.asp?f=hdom_onclick

第一个输入框中添加click事件, 使用 this.value 获取控件的 当前值。

<html>
<body> Field1: <input type="text" id="field1" value="Hello World!" onclick="alert(this.value)">
<br />
Field2: <input type="text" id="field2">
<br /><br />
Click the button below to copy the content of Field1 to Field2.
<br />
<button onclick="document.getElementById('field2').value=
document.getElementById('field1').value; alert(this.text)">Copy Text</button> </body>
</html>

但是 ReactJS设计上, 将UI DOM 和实际上的 virtual DOM进行分离, 实际逻辑在virtual DOM上, 对于本例子, 就是需要将 目标 事件 handler 绑定到 虚拟DOM上。

UI dom上视图组件,调用绑定过this的事件handler。

ReactJS虚拟DOM效应带来的一则副作用探索