4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
新闻详情
React4 事件处理_yuelinana的博客-CSDN博客
来自 : CSDN技术社区 发布时间:2021-03-24

React 内置组件的事件处理

       React 内置组件指的是React中已经定义好的 可以直接使用的如 div、button、input 等与原生 HTML 标签对应的组件

       第一种方式

              a href # οnclick console.info( click me return false; click me /a

               这种方式 用来注册事件的 HTML 属性的值是一个字符串 是一段需要执行的 JavaScript 代码

               可以通过 return false 来阻止当前 HTML 元素的默认行为 如 a 标签的页面跳转

       第二种方式

              a href # id my_link click me /a

              script

                   document.qureySelector( #my_link ).addEventListener( click ,(e) {

                       e.preventDefault();

                       console.info( click me

                   })

              /script

              在React中 事件注册与方式一非常类似 但是有一下不同

                      属性名采用驼峰式(如 onClick onKeyDown) 而不是全小写字母

                      属性值接受一个函数 而不是字符串

                      return false 不会阻止组件的默认行为 需要调用 e.preventDefault()

              示例

                        function ActionLink(){

                           function handleClick(e){

                               e.preventDefault();

                               console.log( The link was clicked

                           }

                           return(

                              a href # onClick {handleClick}

                                   Click me

                             /a

                           )

                        }

               这是一个以函数方式定义的组件 组件渲染一个a元素 设置链接的点击事件 通过事件处理函数接收到了事件对象(e)

               阻止了链接的默认行为 并且打印了 The link was clicked

React 事件对象 VS 原生的 DOM 事件对象

       React 中的事件对象可以称之为 SyntheticEvent(合成对象) 这样做的最大的好处就是可以屏蔽浏览器的差异

       各种厂商的浏览器对规范的实现程度是不一样的 如果直接使用原生DOM事件对象的话 需要考虑浏览器兼容性

       而React通过 SyntheticEvent 使在任何支持 React 的浏览器下 事件对象都有一致的接口

       React 中所有的事件处理函数都会接收到一个SyntheticEvent 的实例 e 作为参数对象 如果在某些特殊的场景中

       需要使用原生的DOM事件对象 可以通过e.nativeEvent 来获取

不要在异步过程中使用 React 事件对象

        React 并不是为每一个事件处理函数生成一个全新的事件对象 事件对象会被复用 当事件处理函数被执行以后

        事件对象的所有属性会被设置成 null 所以在事件处理函数中 不能以异步的方式使用React的事件对象

        因为此时的事件对象的所有属性都是 null 或者已经不是之前的那个事件了

尽量不要使用 addEventListener

         React 内部自己实现了一套高效的事件机制 为了提高框架的性能 React通过DOM事件冒泡 只在 document 节点上注册原生的DOM事件

         React 内部自己管理所有组件的事件处理函数 以及事件的冒泡、捕获

         所以说 如果通过 addEventListener 注册了某个DOM节点的某事件处理函数 并且通过 e.stopPropagation(); 阻断了事件的冒泡或者捕获

         那么该节点下所有的节点上 同类型的 React 事件处理函数都会失效

         示例

                  class CounterLink extends React.Component{

                     constructor(props){

                         super(props);

                         this.state {count:0}

                         this.handleClick this.handleClick.bind(this)

                     }

                     componentDidMount(){

                         document.querySelector( .my-link ).addEventListener( click ,(e) {

                              console.info( raw click

                              e.stopPropagation();

                         })

                     }

                     handleClick(e){

                          e.preventDefault();

                          console.info( react click

                          this.setState({count:this.state.count 1});

                    }

                    render(){

                       return (

                           div className my-link

                                a href # onClick {this.handleClick} Click me {this.state.count} times /a

                           /div

                       )

                    }

                  }

                ReactDOM.render( CounterLink ,document.querySelector( #root ))

        示例中虽然设置了链接的点击事件 但是就无法执行

        示例截图

        \"\"     

如何绑定事件处理函数的 this

        在以类继承的方式定义的组件中 为了能方便的调用当前组件的其他成员方法或属性( 如 : this.state )

        通常需要将事件处理函数运行时的this指向当前组件实例

        示例

                 class Link extends React.Component{

                    constructor(props){

                        super(props);

                        this.state {count:0}

                    }

                    handleClick(e){

                        e.preventDefault();

                        this.setState({count:this.state.count 1})

                    }

                    render(){

                       return a href # onClick {this.handleClick} Click me {this.state.count} times /a

                    }

                 }

                 ReactDOM.render( link/ ,document.querySelector( #root ))

        示例解析

                当点击链接时 控制台会报错 Uncaught TypeError: Cannot read property setState of undefined

                是因为没有将 handleClick 运行时的this绑定到当前组件  

       绑定事件处理函数的 this 到当前组件 有以下几种方式

             第一种方式 通过 bind 方法 原地绑定事件处理函数的 this 指向

                     示例

                             a href # onClick {this.handleClick.bind(this)}

                                  Click me {this.state.count}

                             /a    

                    示例解析

                            这种方式的优点是书写起来相对简单 但是每次渲染都会指向 bind 方法生成一个新的函数 会有额外的开销

                            由于事件处理函数是作为属性传递的 所以从而导致子组件进行重新渲染

             第二种方式 通过一个箭头函数将真实的事件处理函数包装一下

                     示例

                             a href # onClick {e this.handleClick(e)}

                                   Clicked me {this .state.count} times

                             /a

                     示例解析

                             这种方式书写也不麻烦 但是也没有解决第一种方式面临的性能开销和重新渲染的问题

                             不过这种方式的一个好处就是能清晰描述事件处理函数接收的参数列表

             第三种方式 在constructor中 预先将所有的事件处理函数通过bind方法进行绑定

                        示例

                                class Link extends React.Component{

                                   constructor(props){

                                       super(props);

                                       this.state {count:0}

                                      //重点在这里

                                       this.handleClick this.handleClick.bind(this)

                                   }

                                   handleClick(e){

                                       e.preventDefault();

                                       this.setState({count:this.state.count 1})

                                   }                                 

                                   render(){

                                      return a href # onClick {this.handleClick} Click me {this.state.count} times /a

                                   }

                                }

                                ReactDOM.render( link/ ,document.querySelector( #root ))

                           示例解析

                               这种方式能解决前两种方式面临的额外开销和重新渲染的问题 但是写起来略微复杂

                               一个事件处理函数要分别在三个不同的地方进行定义、绑定this和使用

                第四种方式 使用类的成员字段定义语法

                        示例

                                class Link extends React.Component{

                                   constructor(props){

                                       super(props);

                                       this.state {count:0}

                                   }

                                   handleClick e {

                                       e.preventDefault();

                                       this.setState({count:this.state.count 1})

                                   }

                                   render(){

                                       return a href # onClick {this.handleClick} Click me {this.state.count} times /a

                                   }

                                }

                                ReactDOM.render( Link/ ,document.querySelector( #root ))

                         示例解析

                                这种方式解决了上面三种方式面临的性能开销、重新渲染已经书写麻烦的问题

总结

    React中通过设置组件的事件属性来注册事件 React 内部自己实现了一套包括冒泡、捕获逻辑在内的事件在内的事件机制 所以尽量不要用addEventListener

    事件处理函数绑定this的方法有四种 推荐使用类属性定义的方式来定义事件处理函数

    事件对象在 React 中是被复用的 事件回调被执行以后 事件对象所有的属性都会被重置为 null 所以不要在异步的过程中使用事件对象






文件借鉴 http://react-china.org/t/react-react/15548




      

            

              

\"\" \"\" \"\" 点赞 \"\" \"\" 评论

本文链接: http://reactana.immuno-online.com/view-692243.html

发布于 : 2021-03-24 阅读(0)
公司介绍
品牌分类
其他
联络我们
服务热线:4000-520-616
(限工作日9:00-18:00)
QQ :1570468124
手机:18915418616