纵横研究院React技术专题社区

react事件

2019-06-03  本文已影响14人  yoona幻尘

react中,存在两种事件,一种是合成事件,一种是原生事件。原生事件很好理解,基于dom的操作是原生事件,那什么是合成事件呢?

我们在react组件中常见onClick={},这个其实就是合成事件,并且和原生事件onclick十分相似,看下面的例子

class Test extends Component {
    constructor() {
        super(arguments);
        this.onReactClick.bind(this);
    }
    componentDidMount() {
        const parentDom = ReactDOM.findDOMNode(this);
        const childrenDom = parentDom.queneSelector(".button");
        childrenDom .addEventListen('click', this.onDomClick, false);
    }
    onDomClick() {  // 事件委托
        console.log('Javascript Dom click');
    }
    onReactClick() {  // react合成事件
        console.log('React click');
    }
    render() {
        <div>
            <button className="button" onClick={this.onReactClick()}>点击</button>
        </div>
    }
}

componentDidMount里对button进行的操作,就是原生事件,并且原生事件是快于合成事件的。

那么React合成事件和原生事件的区别在哪呢?仅仅只是使用方式吗?
事实上,React并不是将click事件直接绑定在dom上面,而是采用事件冒泡的形式冒泡到document上面,然后React将事件封装给正式的函数处理运行和处理。如果DOM上绑定了过多的事件处理函数,整个页面响应以及内存占用可能都会受到影响。React为了避免这类DOM事件滥用,同时屏蔽底层不同浏览器之间的事件系统差异,实现了一个中间层——SyntheticEvent

当用户在为onClick添加函数时,React并没有将Click事件绑定在 DOM上面。
而是在document处监听所有支持的事件,当事件发生并冒泡至document处时,React将事件内容封装交给中间层SyntheticEvent(负责所有事件合成)
所以当事件触发的时候,对使用统一的分发函数dispatchEvent将指定函数执行。

那么对于原生事件呢?React 也提供了完备的生命周期方法,其中componentDidMount会在组件已经完成安装并且在浏览器中存在真实的 DOM后调用,此时我们就可以完成原生事件的绑定。但是要注意的是,React并不会自动管理原生事件,所以需要我们在卸载组件的时候注销掉原生事件。

有两个需要注意的地方:

阻止事件冒泡

(1)阻止合成事件间的冒泡,用e.stopPropagation();
(2)阻止合成事件与最外层document上的事件间的冒泡,用e.nativeEvent.stopImmediatePropagation();
(3)阻止合成事件与除最外层document上的原生事件上的冒泡,通过判断e.target来避免

componentDidMount() { 
  document.body.addEventListener('click', e => {   
     if (e.target && e.target.matches('div.code')) {  
        return;    
      }    
      this.setState({   active: false,    });   }); 
 }
上一篇 下一篇

猜你喜欢

热点阅读