React事件处理及事件流

Posted 开到荼蘼223's

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React事件处理及事件流相关的知识,希望对你有一定的参考价值。

React事件处理

React事件处理是通过将事件处理器绑定到组建上处理事件,事件触发的同时更新组建的内部状态,内部状态更新会触发组件的重绘

React 元素的事件处理和 DOM 元素的事件处理很相似,但语法上的略有区别

  • 在React中事件的命名采用驼峰命名法,即事件名的首字母为大写,而不是原生DOM中的小写
  • 响应事件的函数要以对象的形式赋值,而不是以DOM字符串的形式

React方式

<button onClick=clickMe()>提交</button>

DOM方式
<button onclick='clickMe()'>提交</button> dom方式

React中事件处理函数

在React中事件处理函数主要有三种写法,不同的写法this指向问题也不同,性能也有所差异

- ES6箭头函数

箭头函数适用于逻辑简单的事件,若逻辑复杂会导致render变得复杂,看不清UI的结构,代码可读性差

    <script type="text/babel">
        class Value extends React.Component
            constructor(props)
                super(props);
                this.state = 
                    value:1
                
            
            render()
                return(
                    <div>
                        <button onClick=(event)=>console.log(this.state.value)>Click Me</button>
                    </div>
                )
            
        
        ReactDOM.render(<Value/>,document.getElementById('text'));
    </script>

按钮中绑定click事件里的this始终指向当前组件Value的实例

- 组件中定义事件函数

因为在自定义函数中this为null,若要在自定义函数中使用this,就必须进行绑定(将this强制绑定到自定义函数中)

    <div id="text"></div>
    <script type="text/babel">
        class MyComponent extends React.Component 
            constructor(props) 
                super(props);
                this.state = 
                    number: 0
                
                // 因为自定义函数中this为null 所以要进行绑定
                this.handelClick = this.handelClick.bind(this)
            
            // 事件处理函数
            handelClick()
                this.state.number++;
                console.log(this.state.number)
            
            render()
                return (
                    <div>      
                    // 调用当前组件实例的事件处理函数                 
                        <button type='button' onClick= this.handelClick >点我</button>
                    </div>
                )
            
        
        ReactDOM.render(<MyComponent />, document.getElementById('text'))
    </script>

这种方法的好处是每次render渲染都不会重新创建一个回调函数,没有额外的性能损失,但是如果在一个组件中有很多的事件函数时这种在构造函数中绑定this的方法会显得繁琐

- 在事件赋值时绑定this

这个方法在每次render时都会重新创建一个新的函数,性能会有一定的损失,但在事件处理函数需要传参数时,这种方法就比较好

    <div id="text"></div>
    <script type="text/babel">
        class MyComponent extends React.Component 
            constructor(props) 
                super(props);
                this.state = 
                    number: 0
                
            
            handelClick()
                ++this.state.number;
                console.log(this.state.number)
            
            render()
                return (
                    <div>            
                    // 在给事件赋值时绑定this          
                        <button type='button' onClick= this.handelClick.bind(this) >点我</button>
                    </div>
                )
            
        
        ReactDOM.render(<MyComponent />, document.getElementById('text'))
    </script>

关于this的绑定
在箭头函数中this指针指向组件的实例对象 不需要进行this绑定
在非箭头函数中若要使用this都必须进行绑定

事件流

react默认的事件流方式:冒泡

    <div id="app"></div>
    <script type="text/babel">
        const style = 
            child: 
                width: '100px',
                height: '100px',
                backgroundColor: 'red'
            ,
            parent: 
                width: '150px',
                height: '150px',
                backgroundColor: '#bfa'
            ,
            ancestor: 
                width: '200px',
                height: '200px',
                backgroundColor: 'green'
            
        
        class App extends React.Component
            render()
                return(
                    <div onClick=()=>console.log('ancestor') style=style.ancestor>
                        <div onClick=()=>console.log('parent') style=style.parent>
                            <div onClick=()=>console.log('child') style=style.child>
                            </div>    
                        </div>    
                    </div>
                )
            
        
        ReactDOM.render(<App />,document.getElementById('app'));

当点击红色区域也就是child 控制台输出依此是

若将事件的触发改为捕获方式,在事件后加Capture即可,若想阻止事件冒泡可以利用事件对象的stopPropagation()方法取消事件冒泡

							<div onClick=(e)=>
                                console.log('child');
                                e.stopPropagation();
                             
                            style=style.child>
                            </div>

此时点击红色区域后控制台只输出child说明阻止冒泡成功

以上是关于React事件处理及事件流的主要内容,如果未能解决你的问题,请参考以下文章

React事件处理及事件流

自己写的一个React事件流处理框架

React事件处理

解析React事件处理的机制及原理

事件流及事件冒泡机制

React 组件中的事件处理组件(受控非受控)函数柯里化