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事件处理的机制及原理

Reactreact概述组件事件

事件流及事件冒泡机制