自动绑定

bind方法

这个方法可以帮助我们绑定事件处理器内的this,并可以向事件处理器中传递参数。

import React, {Component} from 'react';
class App extends Component{
    handClick(e, arg) {
        console.log(e, arg);
    }
    
    render() {
        return <button onClick={this.handleClick.bind(this, 'test')}>Test</button>;
    }
}


构造器内声明

在组件的构造器内完成了this的绑定,这个绑定方式的好处在于仅需要进行一次绑定,而不需要每次调用事件监听器时去执行绑定操作

import React, {Component} from react;
class App extends Component {
    handleClick(e) {
        console.log(e);
        // 在构造器内完成绑定
        this.handClick = this.handClick.bind(this);
    }
    
    render() {
        return <button onClick={this.handClick}>Test</button>
    }
}

箭头函数

箭头函数不仅是函数的"语法糖", 它还自动绑定了定义此函数作用域的this, 因此我们不需要再对它使用bind方法。比如,以下方式就行运行。

import React, {Component} from 'react';

class App extends Component {
    const handClick = (e) => {
        console.log(e);
    };
    
    render () {
        return <button onClick={this.handleClick}>Test</button>;
    }
}

import React, {Component} from 'react';

class App extends Component {
    handClick(e) {
        console.log(e);
    }
    
    render () {
        return <button onClick={() => this.handClick()}>Test</button>;
    }
}

在React 中使用原生事件

import React, {Component} from 'react';

class NativeEventDemo extends Component {
    componentDidMount() {
        this.refs.button.addEventsListener('click', e=>{
            handClick(e);
        })
    }
    
    handClick(e) {
        console.log(e);
    }
    
    componentWillUnmount() {
        this.refs.button.removeEventListener('click');
    }
    
    render() {
        return <button ref="button">Test</button>
    }
}

尽量避免在React中混用合成事件和原生DOM事件。另外,用reactEvent.nativeEvent.stopPropagation()来阻止冒泡是不行的。阻止React事件冒泡的行为只用用于React合成事件系统中,且没 办法阻止原生事件的冒泡。反之,在原生事件中的阻止冒泡行为,却可以组织React合成事件的传播。

实际上,React的合成事件系统只是原生DOM事件系统的一个子集。它仅仅实现了DOM Level3的事件接口,并且统一了浏览器间的兼容问题。有些事件React并没有实现,或者受某些限制没办法去实现,比如window的resize事件。

对于无法使用React合成事件的场景,我们海需要使用原生事件来实现。

阻止原生事件传播需要使用e.preventDefault(), 不过对于不支持该方法的浏览器(IE9以下),只能使用e.cancelBubble = true来阻止。而在React合成事件中,只需要使用e.preventDefault()即可。


小渝人儿
1.1k 声望849 粉丝

前端工程师