ReactJS虚拟DOM一则例证

疑问

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

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

this.handleClick = this.handleClick.bind(this)
 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <meta charset="UTF-8" />
 5     <script src="../build/react.development.js"></script>
 6     <script src="../build/react-dom.development.js"></script>
 7     <script src="../build/babel.min.js"></script>
 8   </head>
 9   <body>
10     <div id="example"></div>
11     <script type="text/babel">
12       class LikeButton extends React.Component {
13         constructor(props) {
14           super(props)
15           this.state = {
16             liked: false
17           }
18           this.handleClick = this.handleClick.bind(this)
19         }
20         handleClick(event) {
21           this.setState({ liked: !this.state.liked });
22         }
23         render() {
24           var text = this.state.liked ? 'like' : 'haven\'t liked';
25           return (
26             <p onClick={this.handleClick}>
27               You {text} this. Click to toggle.
28             </p>
29           );
30         }
31       }
32 
33       ReactDOM.render(
34         <LikeButton />,
35         document.getElementById('example')
36       );
37     </script>
38   </body>
39 </html>

 

实验

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

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <meta charset="UTF-8" />
 5     <script src="../build/react.development.js"></script>
 6     <script src="../build/react-dom.development.js"></script>
 7     <script src="../build/babel.min.js"></script>
 8   </head>
 9   <body>
10     <div id="example"></div>
11     <script type="text/babel">
12       class LikeButton extends React.Component {
13         constructor(props) {
14           super(props)
15           this.state = {
16             liked: false
17           }
18           //this.handleClick = this.handleClick.bind(this)
19         }
20         handleClick(event) {
21           this.setState({ liked: !this.state.liked });
22         }
23         render() {
24           var text = this.state.liked ? 'like' : 'haven\'t liked';
25           return (
26             <p onClick={this.handleClick}>
27               You {text} this. Click to toggle.
28             </p>
29           );
30         }
31       }
32 
33       ReactDOM.render(
34         <LikeButton />,
35         document.getElementById('example')
36       );
37     </script>
38   </body>
39 </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一则例证

 

上一篇:关于React之JSX语法理解


下一篇:组件中使用事件函数