React中的事件处理

  React 中文官网中有提到:"你必须谨慎对待 JSX 回调函数中的 this,类的方法默认是不会绑定 this 的" 。 "这并不是 React 的特殊行为;它是函数如何在 JavaScript 中运行的一部分"  。因此,如果忘记绑定,对应函数的 this 的值会是 undefined。当然,在没有用到函数的 this 的时候,绑定就不是必要的了。下面主要是从两个部分对 React 中的事件处理进行理解:第一部分是事件函数仅在在当前组件中进行事件处理,第二部分是将事件函数传递给其他组件进行事件处理。每部分分为用到 this 的事件函数,和没有用到 this 的事件函数。第一部分中例子使用没有传递参数,第二部分中使用参数。最后例中也同样展示了函数的几种绑定方式。

对 react 中的事件处理关注的重点可以总结为两点: ①  this 是否为当前上下文 ② 传递给事件处理程序的参数是从哪里来的

一、事件处理:事件函数仅在在当前组件中(例中没有传递参数,传递参数的情况与之类似)

1、没有用到事件处理程序中的 this 时

代码如下:

 1 var React = require('react');
 2 var ReactDOM = require('react-dom');
 3 class Index extends React.Component {
 4     constructor() {
 5         super(); //调用基类的所有的初始化方法
 6          7     };
 8
 9     showName(){
10         alert('username: "Guang"');
11     }
12
13     render() {
14         return (
15             <div>
16                         {/* 传递数据: 不传递参数或者有传递参数但是不涉及事件处理程序中的 this ,对事件处理程序的绑定:不是必须的 */}
17                         <input type="button" value="显示名称 没有绑定" onClick={this.showName}></input><br></br>
18                         <input type="button" value="显示名称 箭头函数绑定" onClick={()=>this.showName()}></input><br></br>
19                         <input type="button" value="显示名称 bind绑定" onClick={this.showName.bind(this)}></input>
20                         {/* 也可以在构造函数中通过: this.showName=this.showName.bind(this); 语句来绑定 */}
21             </div>
22         );
23     }
24 }
25 ReactDOM.render(
26     <Index/>, document.getElementById('example'));

运行结果:

2、用到事件处理程序中的 this 时

代码如下:

 1 var React = require('react');
 2 var ReactDOM = require('react-dom');
 3 class Index extends React.Component {
 4     constructor() {
 5         super(); //调用基类的所有的初始化方法
 6         this.state = {
 7             username: "Guang",
 8             age: 20,
 9             newage1:"9 changeAge1",
10             newage2:"99 changeAge2",
11             newage3:"999 changeAge3"
12         };
13     };
14
15     changeAge1(){
16         this.setState({age:this.state.newage1});
17     };
18     changeAge2(){
19         this.setState({age:this.state.newage2});
20     };
21     changeAge3(){
22         this.setState({age:this.state.newage3});
23     };
24
25     render() {
26         return (
27             <div>
28                 <p>age:{this.state.age}</p>
29                 {/* 传递数据: 不传递参数但是涉及到事件处理程序中的 this ,对事件处理程序的绑定:是必须的 */}
30                 <input type="button" value="更改 age, 没有绑定" onClick={this.changeAge1}></input><br></br>
31                 <input type="button" value="更改 age, 箭头函数绑定" onClick={()=>this.changeAge2()}></input><br></br>
32                 <input type="button" value="更改 age, bind绑定" onClick={this.changeAge3.bind(this)}></input>
33                 {/* 也可以在构造函数中通过: this.changeAge3=this.changeAge3.bind(this); 语句来绑定 */}
34             </div>
35         );
36     }
37 }
38 ReactDOM.render(
39     <Index/>, document.getElementById('example'));

运行结果: 可以看到,在需要用到事件处理程序中的 this 时,如果没有对事件处理程序进行绑定,会报错。而对事件处理程序进行绑定后正确运行

  

二、事件处理:事件函数传递到其他组件中(例中有传递参数,没有传递参数的情况与之类似)

1、没有用到事件处理程序中的 this 时(当传递的参数只有事件对象无其他数据时)

父组件代码如下:

 1 var React = require('react');
 2 var ReactDOM = require('react-dom');
 3 import BodyChild from './components/bodychild';
 4 class Index extends React.Component {
 5
 6     // 该函数将获取的事件保持在 this.state.eventobject 中
 7     parentEventHandler(e){
 8         alert(e.target.value);
 9     }
10
11     render() {
12         return (
13             <div>
14                     {/* 事件处理:事件函数传递给其他组件 */}
15                     {/* 传递的数据: 传递参数 只有事件对象 无其他数据 但是没有用到事件处理程序的 this */}
16                     <BodyChild
17                         // 匿名函数赋值给子组件的 this.props.childAnonymous ,匿名函数后面的 bind(this) 是传入当前上下文,使得匿名函数内的 this 为当前上下文
18                         childAnonymous={function(e){this.parentEventHandler(e)}.bind(this)}
19                         // 箭头函数将函数 this 设置为当前上下文
20                         childArrow={(e)=>this.parentEventHandler(e)}
21                         // 使用 bind 将函数 this 设置为当前上下文
22                         childBind={this.parentEventHandler.bind(this)}
23                         // 也可以在构造函数中通过: this.childBind=this.parentEventHandler.bind(this) 语句来绑定
24                     />
25             </div>
26         );
27     }
28 }
29 ReactDOM.render(
30     <Index/>, document.getElementById('example'));

子组件代码如下:

 1 import React from 'react';
 2 export default class BodyChild extends React.Component{
 3
 4   render(){
 5     return(
 6       <div>
 7             {/* 匿名函数后面的 bind(this) 是传入当前上下文,使得匿名函数内的 this 为当前上下文 */}
 8             <input type="button" value="childAnonymous 匿名函数传参 无绑定" onClick={function(e){this.props.childAnonymous(e)}}></input><br></br>
 9             <input type="button" value="childAnonymous 匿名函数传参 匿名函数使用 bind 绑定" onClick={function(e){this.props.childAnonymous(e)}.bind(this)}></input><br></br>
10
11             {/*
12                 对于箭头函数绑定过程的个人理解
13                 使用箭头函数 this 被设置为当前箭头函数所在的上下文,其原理有点类似于下面的过程(并不是说过程就是这样的,只是原理与之类似,个人理解)
14                 源代码:
15                 <input type="button" onClick={(parameters)=>FunctionName(parameters)}/></input>
16                 过程原理:
17                 function anonymous(parameters){
18                   // 通过某种方式,将函数绑定当前上下文,将 this 设置为当前上下文(比如: FunctionName.bind(当前上下文))
19                   // 通过某种方式,将参数 parameters 传递给 FunctionName(比如:FunctionName(parameters))
20                 }
21                 <input type="button" onClick=anonymous /></input>
22             */}
23             <input type="button" value="childArrow 箭头函数传参 箭头函数绑定" onClick={(e)=>this.props.childArrow(e)}></input><br></br>
24
25             {/* 通过箭头函数的方式,事件对象必须显式的进行传递,但是通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。 */}
26             <input type="button" value="childBind 直接传参 bind 绑定" onClick={this.props.childBind.bind(this)}></input>
27         </div>
28     )
29   }
30 }

运行结果:可以看到,在没有用到事件处理程序的 this 时,无论是父组件还是子组件中,若没有绑定事件处理程序会报错,这是由于函数从父组件传递到子组件后,子组件需要调用传递过来的函数(子组件要调用传递过来的函数就要用到 this ,因此匿名函数需要绑定当前上下文。又由于需要传递一个事件参数,无论是通过使用箭头函数还是使用 bind ,都会完成对事件处理程序的绑定),因此几种情况都要绑定,前者是绑定匿名函数,后两者是对事件处理程序进行绑定。

2、用到事件处理程序的 this 时

由于不需要用到事件处理程序的 this 时都需要绑定事件处理程序,因此要用到事件处理程序的 this 的情况下必然要绑定事件处理程序,用法与上面相同。

3、给事件处理程序传递多个参数,参数没有事件对象,只有其他参数时

父组件代码如下:

 1 var React = require('react');
 2 var ReactDOM = require('react-dom');
 3 import BodyChild from './components/bodychild';
 4 class Index extends React.Component {
 5
 6     constructor(){
 7         super();
 8         this.state={
 9             p1:"等待第一个数据",
10             p2:"等待第二个数据"
11         }
12     }
13
14     parentAnonymous(param1,param2){
15         this.setState({
16             p1:param1,
17             p2:param2
18         })
19     }
20
21     parentArrow(param1,param2){
22         this.setState({
23             p1:param1,
24             p2:param2
25         })
26     }
27
28     parentBind(param1,param2){
29         this.setState({
30             p1:param1,
31             p2:param2
32         })
33     }
34
35     render() {
36         return (
37             <div>
38                     <p>从子组件中获取到的数据:<b>参数一:</b>{this.state.p1} ,<b>参数二:</b> {this.state.p2}</p>
39                     <BodyChild
40                         // 使用匿名函数的方式 匿名函数后面的 bind(this) 是传入当前上下文,使得匿名函数内的 this 为当前上下文
41                         childAnonymous={function(param1,param2){this.parentBind(param1,param2)}.bind(this)}
42                         // 箭头函数将函数 this 设置为当前上下文
43                         childArrow={(param1,param2)=>this.parentArrow(param1,param2)}
44                         // 使用 bind 将函数 this 设置为当前上下文
45                         childBind={this.parentBind.bind(this)}
46                     />
47             </div>
48         );
49     }
50 }
51 ReactDOM.render(
52     <Index/>, document.getElementById('example'));

子组件代码如下:

 1 import React from 'react';
 2 export default class BodyChild extends React.Component{
 3
 4   constructor(props){
 5     super(props);
 6     this.state={
 7       name:"anonymous",
 8       age:20,
 9       nameforarrow:"arrow",
10       ageforarrow:"99+",
11       nameforbind:"bind",
12       ageforbind:"81192/81194",
13     }
14   }
15
16   render(){
17     return(
18       <div>
19             {/* 使用匿名函数的方式 匿名函数后面的 bind(this) 是传入当前上下文,使得匿名函数内的 this 为当前上下文*/}
20             <input type="button" value="匿名函数 bind 绑定" onClick={function(){this.props.childAnonymous(this.state.name,this.state.age)}.bind(this)}></input>
21             {/* 通过箭头函数的方式 */}
22             <input type="button" value="箭头函数传参 箭头函数绑定" onClick={()=>this.props.childArrow(this.state.nameforarrow,this.state.ageforarrow)}></input>
23             {/* 通过 bind 的方式,虽然本例中不需要传递事件对象,但是事件对象以及更多的参数将会被隐式的进行传递 */}
24             <input type="button" value="直接传参 bind 绑定" onClick={this.props.childBind.bind(this,this.state.nameforbind,this.state.ageforbind)}></input>
25         </div>
26     )
27   }
28 }
29
30           

运行结果:

4、给事件处理程序传递的多个参数既有事件对象又有其他参数时

父组件代码如下:

 1 var React = require('react');
 2 var ReactDOM = require('react-dom');
 3 import BodyChild from './components/bodychild';
 4 class Index extends React.Component {
 5
 6     constructor(){
 7         super();
 8         this.state={
 9             value:"等待与事件有关的数据",
10             p1:"等待第一个数据",
11             p2:"等待第二个数据"
12         }
13     }
14
15     // 由于通过箭头函数的方式,事件对象必须显式的进行传递,在子组件中 e 为第一个参数,传参格式如下
16     parentEventHandler(e,param1,param2){
17         this.setState({
18             value:e.target.value,
19             p1:param1,
20             p2:param2
21         })
22     }
23
24     // 通过 bind 方式向监听函数传参,在类组件中定义的监听函数,事件对象 e 要排在所传递参数的后面,传参格式如下
25     parentEventHandlerForBind(param1,param2,e){
26         this.setState({
27             value:e.target.value,
28             p1:param1,
29             p2:param2
30         })
31     }
32
33     render() {
34         return (
35             <div>
36                     <p>从子组件中获取到的数据:<b>值:</b>{this.state.value} ,<b>参数一:</b>{this.state.p1} ,<b>参数二:</b> {this.state.p2}</p>
37                     <BodyChild
38                         // 箭头函数将函数 this 设置为当前上下文
39                         childArrow={(e,param1,param2)=>this.parentEventHandler(e,param1,param2)}
40                         // 使用 bind 将函数 this 设置为当前上下文
41                         childBind={this.parentEventHandlerForBind.bind(this)}
42                         // 也可以通过匿名函数绑定后传参 childBind={function(param1,param2,e){this.parentEventHandlerForBind(param1,param2,e)}.bind(this)}
43                     />
44             </div>
45         );
46     }
47 }
48 ReactDOM.render(
49     <Index/>, document.getElementById('example'));

子组件代码如下:

 1 import React from 'react';
 2 export default class BodyChild extends React.Component{
 3
 4   constructor(props){
 5     super(props);
 6     this.state={
 7       name:"Guang",
 8       age:20,
 9       nameforbind:"Guang Zai",
10       ageforbind:"99+"
11     }
12   }
13
14   render(){
15     return(
16       <div>
17             {/* 通过箭头函数的方式,事件对象必须显式的进行传递 */}
18             <input type="button" value="箭头函数传参 箭头函数绑定" onClick={(e)=>this.props.childArrow(e,this.state.name,this.state.age)}></input><br></br>
19
20             {/* 通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递 */}
21             <input type="button" value="直接传参 bind 绑定" onClick={this.props.childBind.bind(this,this.state.nameforbind,this.state.ageforbind)}></input>
22
23         </div>
24     )
25   }
26 }

运行结果如下:

转载于:https://www.cnblogs.com/go4it/p/9556255.html

React 事件处理相关推荐

  1. React事件处理函数传参问题

    React事件处理函数参数 HTML标签与React 组件是不同的,事件对象e是HTML标签元素的,组件没有的. 转载于:https://www.cnblogs.com/zhansu/p/848232 ...

  2. react 事件处理_在React中处理事件

    react 事件处理 在使用React渲染RESTful服务后,我们创建了简单的UI,用于渲染从RESTful服务获取的员工列表. 作为本文的一部分,我们将扩展同一应用程序以支持添加和删除员工操作. ...

  3. React事件处理及事件流

    React事件处理 React事件处理是通过将事件处理器绑定到组建上处理事件,事件触发的同时更新组建的内部状态,内部状态更新会触发组件的重绘 React 元素的事件处理和 DOM 元素的事件处理很相似 ...

  4. react事件处理函数中绑定this的bind()函数

    问题引入 import React, { Component } from 'react'; import {Text,View } from 'react-native';export defaul ...

  5. 0205事件处理_受控_柯里化-组件-React

    文章目录 1 事件处理 1.1 概述 1.2 示例 2 非受控组件和受控组件 2.1 概述 2.2 登录示例-非受控 2.3 登录示例-受控 3 高阶函数 4 函数柯里化 5 React函数的非柯里化 ...

  6. React 组件 API

    设置状态:setState 替换状态:replaceState 设置属性:setProps 替换属性:replaceProps 强制更新:forceUpdate 获取DOM节点:findDOMNode ...

  7. react 动态添加组件属性_这么高质量React面试题(含答案),看到就是赚到了!...

    前言 本文篇幅较长,全是干货,建议亲们可以先收藏慢慢看哦 写文不易,欢迎大家一起交流,喜欢文章记得关注我点个赞哟,感谢支持! Q1 :什么是虚拟DOM? 难度::star: 虚拟DOM(VDOM)它是 ...

  8. React事件系统研究总结

    React作为目前前端业界最流行的mvvm框架之一已经被广大前端同学所熟知,而在日常工作中已经熟悉使用React的我们对React内部的工作流程.设计理念是否又有足够的了解呢?本文是对于React事件 ...

  9. react java编程_快速上手React编程 PDF 下载

    资料目录: 第1章  初积React  3 1.1  什么是React  4 1.2 React解决的问题  5 1.3  使用React的好处  6 1.3.1  简单性  6 1.3.2  速度和 ...

  10. react 显示当前时间_React 灵魂 23 问,你能答对几个?

    1.setState 是异步还是同步? 合成事件中是异步 钩子函数中的是异步 原生事件中是同步 setTimeout中是同步 相关链接: 你真的理解setState吗? 2.聊聊 react@16.4 ...

最新文章

  1. 【转】volatile关键字。编译器不优化,多线程会改。防止随时变动的
  2. Spring Boot文件上传
  3. [转]“Ceph浅析”系列之(—)—Ceph概况
  4. Python numpy中矩阵的用法总结
  5. Java—筛选法求素数
  6. matlab如何求空间一点到直线距离,空间点到直线距离怎么求
  7. Dual Thrust(期货)
  8. 2019年通信工程考研初试经验帖(366分)
  9. ShadowGun之Shader分析
  10. 微信小程序: 摇色子
  11. 【摄影笔记三】光圈和快门
  12. Ubuntu磁盘扩容(简单亲测有效)
  13. 宽带、专线等傻傻分不清楚——广域网协议
  14. PictureMerge
  15. html认识时间游戏,认识时间教学设计
  16. Android Button 英文大小写问题
  17. RT-Thread 移植是stm32F429 pwm例程
  18. JavaEE - 面向对象-构造方法、封装、类加载过程
  19. Hive中4个By的区别
  20. 【SDIO】SD2.0协议分析总结(二)-- SD卡识别数据传输过程

热门文章

  1. 【Faster R-CNN论文精度系列】原文精析
  2. 证明三角形中cosA+cosB+cosC=1+4sin(A/2)sin(B/2)sin(C/2)
  3. safenet 超级狗 加密狗
  4. 双级矩阵变换器matlab,双空间矢量调制下双级矩阵变换器的谐波分析
  5. 红外线体温计详细制作方案
  6. Matlab 可见光波段植被指数
  7. iOS SpriteKit 小游戏开发实例 - Flappy Bird
  8. 阴阳师1月服务器维护,阴阳师1月15日更新维护公告 鬼童丸降临平安京
  9. Eclipse设置编辑器为绿豆沙颜色
  10. DAY7(DAY8拓展):Python基础及内置库介绍与使用(含例题)