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

更新日期: 2018-08-31阅读量: 1894标签: 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

React 中请求远程数据的四种方法

React 是一个专注的组件库。因此,它对如何请求远程数据没有什么建议。如果要通过 HTTP 请求数据并将其发送到 Web API ,可以考虑下面四种方法。

React Server Component 可能并没有那么香

前段时间 React 团队发布了一项用于解决 React 页面在多接口请求下的性能问题的解决方案 React Server Components。当然该方案目前还在草案阶段,官方也只是发了视频和一个示例 demo 来说明这个草案。

Context - React跨组件访问数据的利器

Context提供了一种跨组件访问数据的方法。它无需在组件树间逐层传递属性,也可以方便的访问其他组件的数。在经典的React应用中,数据是父组件通过props向子组件传递的

react 高阶组件的 理解和应用

react 高阶组件简单的理解是:一个包装了另一个基础组件的组件。高阶组件的两种形式:属性代理(Props Proxy)、反向继承 (Inheritance Inversion)

react router中页面传值的三种方法

这篇文章主要介绍React Router定义路由之后如何传值,有关React和React Router 。react router中页面传值的三种方法:props.params、query、state

怎样使用React Context API

React Context API 现在已经成为一个实验性功能,但是只有在 React 16.3.0 中才能用在生产中。本文将向你展示两个基本的 Web 商店应用程序,一个使用了 Context API 进行构建,另一个则不用。

自定义组件v-model的实质性理解

在React中如果想实现类似于v-model的功能,一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不同的目的

渐进式React

可以说 React 为Web开发者带来了全新的开发模式,而在各类新功能下,如何达到性能最优仍是我们需要关心的。今天做一次精读尝试,原文地址在文末,话不多说,先呈上一份性能清单:

从 React 切换到 Vue.js

React 和 Vue 的关系有点像可口可乐和百事可乐,你在 React 中做的很多事情都可以在 Vue 中完成。当然这里也存在一些重要的概念差异,其中一些反映了 Angular 对 Vue 的影响。

为什么我会选择React+Next.js,而不是Vue或Angular?

本文的目的不是要对 React、Vue 和 Angular 三者进行比较,已经有许多人对这个话题进行了比较深入的探讨。每个人都有自己的偏好。与其他库和框架相比,我更喜欢使用 React 构建用户界面。 对我来说,这是构建用户界面唯一正确的方法,它让我爱上了 React。

点击更多...

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