React中的处理事件_React如何处理事件

时间: 2018-08-31阅读: 1836标签: react

今天我们主要说一下react是如何处理事件的。事件的处理是前端开发过程中非常重要的一部分,通过事件处理,我们可以响应用户的各种操作,从而实现一个富交互的应用。


react事件处理VS原生Dom事件处理

两者在事件处理方面极其类似,只是在一些语法上稍有不同: 
* React 事件绑定属性的命名采用驼峰式写法(如:onClick,onKeyUp),而不全是小写字母。 
* 如果采用 jsX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM 元素的写法)。

原生DOM事件写法:

<input type="button" onclick="fn()">

React中写法:

<input type="button" onClick={fn}>
  • 另外在React当中,return false不会阻止事件的默认行为,需要调用 e.preventDefault(); 例如,通常我们在 html 中阻止链接默认打开一个新页面,可以这样写:
<a href="#" onclick="console.log('点击链接'); return false">
  你来点我呵
</a>

而在React中要这样写:

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('链接被点击');
  }

  return (
    <a href="#" onClick={handleClick}>
      点我
    </a>
  );
}


绑定事件处理函数的this问题

在以类继承的方法定义的组件中,事件处理函数的this指向的并不是当前组件。

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name:"老大",
            age: 0
        }
    }
    addOneClick(e) {
        e.preventDefault();
        /*此处的this并没有指向,所以会报错:
        * Uncaught TypeError: Cannot read property 'setState' of undefined*/
        this.setState({ age: this.state.age + 1 })
    }
    render() {
        return <div>
            <a href="#" onClick={this.addOneClick}>点我啊</a>
            {this.state.name}今年{this.state.age}岁了!
        </div>;
    }
}
var element = <MyComponent/>;
ReactDOM.render(
    element,
    document.querySelector("#wrap")
);

以上示例在点击链接时,会报错:Uncaught TypeError: Cannot read property ‘setState’ of undefined。因为this指向的并不是该组件。所以为了能方便调用当前组件的其他属性或方法,需要将this指向为当前实例


绑定事件处理函数的this到当前组件,有四种方法:

1、通过bind方法进行原地绑定,从而改变this指向:

render() {
    return <div>
        <a href="#" onClick={this.addOneClick.bind(this)}>点我啊</a>
        {this.state.name}今年{this.state.age}岁了!
    </div>;
}

该种方式写起来比较简单,但是每次执行bind方法都会生成一个新的函数,势必会有额外的开销,明显这并不是一种好的方法。


2、通过箭头函数

render() {
    return <div>
        <a href="#" onClick={e => this.addOneClick(e)}>点我啊</a>
        {this.state.name}今年{this.state.age}岁了!
    </div>;
}

这种写法也不是特别麻烦,不过依然也会有一丢丢的性能开销问题。


3、在constructor中提前对事件进行绑定:

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name:"老大",
            age: 0
        };
        //在此处提前绑定
        this.addOneClick=this.addOneClick.bind(this);
    }
    addOneClick(e) {
        e.preventDefault();
        this.setState({ age: this.state.age + 1 })
    }
    render() {
        return <div>
            <a href="#" onClick={this.addOneClick}>点我啊</a>
            {this.state.name}今年{this.state.age}岁了!
        </div>;
    }
}
var element = <MyComponent/>;
ReactDOM.render(
    element,
    document.querySelector("#wrap")
);

以上这种写法自带尿点。虽然没有额外开销,但写起来有些复杂。以后要对每个事件都要在构造器中再进行一次绑定。


4、将事件的写法改为箭头函数的形式

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name:"老大",
            age: 0
        }
    }
    //在此处采用箭头函数写法
    addOneClick=(e) => {
        e.preventDefault();
        this.setState({ age: this.state.age + 1 })
    }
    render() {
        return <div>
            <a href="#" onClick={this.addOneClick}>点我啊</a>
            {this.state.name}今年{this.state.age}岁了!
        </div>;
    }
}
var element = <MyComponent/>;
ReactDOM.render(
    element,
    document.querySelector("#wrap")
);

是不是很不错?


向事件处理函数传递参数

现在咱们要将之前为年龄加1的案例进行一下调整!调整为当点击时根据传递的参数来决定加几!比如传2,点击一次加2。传递参数有两种方法:


1、通过箭头函数

其实也就是在箭头函数内,调用事件处理函数。

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name:"老大",
            age: 0
        }
    }
    addOneClick(num,e){
        e.preventDefault();
        this.setState({ age: this.state.age + num })
    }
    render() {
        return <div>
            <a href="#" onClick={(e) => this.addOneClick(2, e)}>点我啊</a>
            {this.state.name}今年{this.state.age}岁了!
        </div>;
    }
}
var element = <MyComponent/>;
ReactDOM.render(
    element,
    document.querySelector("#wrap")
);

2、通过bind

  • 通过 bind 方式向监听函数传参,在类组件中定义的监听函数,事件对象 e 要排在所传递参数的后面
class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name:"老大",
            age: 0
        }
    }
    addOneClick(num,e){
        e.preventDefault();
        this.setState({ age: this.state.age + num })
    }
    render() {
        return <div>
            <a href="#" onClick={this.addOneClick.bind(this,2)}>点我啊</a>
            {this.state.name}今年{this.state.age}岁了!
        </div>;
    }
}
var element = <MyComponent/>;
ReactDOM.render(
    element,
    document.querySelector("#wrap")
);


来源:https://blog.csdn.net/u012149969/article/details/82215494


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: https://www.fly63.com/article/detial/1044

Webpack5 搭建React多页面应用

react-multi-page-app 是一个基于 webpack5 搭建的 react 多页面应用。为什么搭建多页面应用:多个页面之间业务互不关联,页面之间并没有共享的数据

如何写出漂亮的 React 组件

在Walmart Labs的产品开发中,我们进行了大量的Code Review工作,这也保证了我有机会从很多优秀的工程师的代码中学习他们的代码风格与样式。在这篇博文里我会分享出我最欣赏的五种组件模式与代码片。不过我首先还是要谈谈为什么我们需要执着于提高代码的阅读体验

react-navigation 监听顶部导航栏点击/滑动状态

使用createMaterialTopTabNavigator创建顶部导航栏,希望实现切换到指定的Tab再获取数据,查看官方文档只能找到tabBarOnPress 方法监听点击回调,但是无法监听滑动切换

解读React的pooledClass.js_对象池技术的原理/思路

单例模式是限制了一个类只能有一个实例,对象池模式则是限制一个类实例的个数。对象池技术基本原理的核心有两点:缓存和共享,即对于那些被频繁使用的对象,在使用完后,不立即将它们释放,而是将它们缓存起来

react-router 路由切换动画

因为项目的需求,需要在路由切换的时候,加入一些比较 zb 的视觉效果,所以研究了一下。把这些学习的过程记录下来,以便以后回顾。同时也希望这些内容能够帮助一些跟我一样的菜鸟,让他们少走些坑。可能我对代码的表述不是很到位,希望大家不要介意。机智的你们一定可以看明白。

解读vue-server-renderer源码并在react中的实现

在博客开发的过程中,有这样一个需求想解决,就是在SSR开发环境中,服务端的代码是是直接通过webpack打包成文件,因为里面包含同构的代码,就是服务端与客户端共享前端的组件代码

useEffect引起的React Hooks深入了解

在进入正式阅读之前,最好先思考一下下面的问题:React Hooks真的有生命周期吗?React Hooks的函数里面定义的函数或者变量会被缓存吗,这样下次再调用组件的时候就可以不用重新声明了。

必须要会的 50 个React 面试题

如果你是一位有抱负的前端程序员并准备面试,那么这篇文章很适合你。本文是你学习和面试 React 所需知识的完美指南。JavaScript 工具缓慢而稳定地在市场中扎根,对 React 的需求呈指数级增长。选择合适的技术来开发应用或网站变得越来越有挑战性

React创建组件的三种方式及其区别

React推出后,出于不同的原因先后出现三种定义react组件的方式,殊途同归;具体的三种方式:函数式定义的无状态组件、es5原生方式React.createClass定义的组件、es6形式的extends React.Component定义的组件

grpc-web与react的集成

使用create-react-app脚手架生成react相关部分,脚手架内部会通过node自动起一个客户端,然后和普通的ajax请求一样,和远端服务器进行通信,只不过这里采用支持rpc通信的grpc-web来发起请求,远端采用docker容器的node服务器,node服务器端使用envoy作为代理

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!