• 每日质量NPM包事件绑定_bindme(详解React的this)


    一、bindme

    官方定义: is a helper to bind a list of methods to an object reference

    理解: 因为不推荐在render()里构建函数,作者就用了6行代码封装了函数绑定事件的代码.
    bindme的npm包实际上由6行ES5代码组成,但是确实方便了很多.这个包值得一用

    二、用法

    代替箭头函数和多层bind

    有时候我们并不会直接在创建事件的时候`bind`,而是统一在constructor上绑定事件,如果一个模块大起来,就会出现好几十行绑定事件的代码,用`bindme`可以很好解决.例如 ``` //原写法 this.clickEvent1 = this.clickEvent1.bind(this) this.clickEvent2 = this.clickEvent2.bind(this) this.clickEvent3 = this.clickEvent3.bind(this) this.clickEvent4 = this.clickEvent4.bind(this) this.clickEvent5 = this.clickEvent5.bind(this)

    //bindme写法
    bindme(this, 'clickEvent1', 'clickEvent2', 'clickEvent3', 'clickEvent4', 'clickEvent5')

    又好看又方便
    
    也可以在`super`构建实例的时候绑定
    

    bindme(super(props),
    'clickEvent1',
    'clickEvent2',
    'clickEvent3',
    'clickEvent4',
    'clickEvent5',
    )

    
    就是这么简单的用法, 我们可以看看它的源码转换成ES6是怎么样的
    

    const bindme = (self, ...funcs) => {
    funcs.forEach(func => {
    if (self[func]) {
    self[func] = self[func].bind(self)
    } else {
    console.error(Method ${func} is not defined)
    }
    })
    }

    
    其实也就是收集所有的事件,再统一bind,如果不存在的抛出异常.我们在平时也会经常封装一些类似这些小的便捷操作
    
    <h3>结合React</h3>
    

    import React,{ PureComponent } from 'react'

    import bindme from 'bindme'
    import './style.css'
    export default class BindmeComp extends PureComponent{
    constructor(props){
    bindme(super(props),
    'bindmeOnMouseOver'
    )

        this.initClickMode = this.initClickMode.bind(this)
        
        bindme(this, 'bindmeFirClickMode', 'bindmeSecClickMode')
    }
    
    noThisClickMode(){
        console.log('未绑定this事件 =========>', this)
    }
    
    initClickMode(){
        console.log('普通bind事件 ===========>', this)
    }
    
    arrowClickMode = () => {
        console.log('箭头函数bind事件 ===========>', this)
    }
    
    bindmeFirClickMode(){
        console.log('bindme事件1 ===========>', this)
    }
    
    bindmeSecClickMode(){
        console.log('bindme事件2 ===========>', this)
    }
    
    bindmeOnMouseOver(){
        console.log('bindme事件3 ===========>', this)
    }
    
    render(){
        return(
            <div>
                <div className="list">
                    <span>未绑定this事件</span>
                    <button onClick={ this.noThisClickMode }>点击</button>
                </div>
                <div className="list">
                    <span>普通bind事件</span>
                    <button onClick={ this.initClickMode }>点击</button>
                </div>
                <div className="list">
                    <span>箭头函数事件</span>
                    <button onClick={ this.arrowClickMode}>点击</button>
                </div>
                <div className="list">
                    <span>bindme</span>
                    <button onClick={ this.bindmeFirClickMode }>点击</button>
                </div>
                <div className="list">
                    <span>bindme2</span>
                    <button onClick={ this.bindmeSecClickMode } >点击</button>
                </div>
    
                <div className="list">
                    <span>bindme3</span>
                    <button onMouseOver={ this.bindmeOnMouseOver } >滑过</button>
                </div>
            </div>
        )
    }
    

    }

    
    ![](https://img2018.cnblogs.com/blog/1414709/201810/1414709-20181002151152656-431142478.png)
    
    上面基本覆盖了常用的事件绑定情况.我们看看都会输出什么?
    
    ![](https://img2018.cnblogs.com/blog/1414709/201810/1414709-20181002151326789-2063352033.png)
    
    可以看到,除了第一个this为undefined外,其他都是正常绑定在了组件上
    
    <h3>扩展一下React的this</h3>
    我们先从我们最熟悉js的`this`说起;  
    
    面试官经常会问,什么是this?this指向什么?
    一般来说:  
    <b>谁调用该`function`,该函数的this就指向这个调用方</b>
    
    有一个特殊的情况,ES6的箭头函数,也是面试官特别喜欢的一个东西(但它确实好用),由于箭头函数不存在this,所以它的this是由上一层继承而来的.所以可以得出结论<b>箭头函数的this始终指向构造时的对象,而不是使用时的对象</b>
    
    另外箭头函数还有一些不同于普通函数的特性,比如: 不可以当作构造函数使用,即不可以`new`. 不可以使用`arguments`属性等等
    
    总结一句话就是:
    <b>普通函数this是动态的,而箭头函数的this是静态的</b>
    
    <h4>我们细说一下React的this.  </h4>
    因为React组件是通过`class`构造的,所以组件里的所有属性,所有方法都可以通过this来获取,例如我们经常使用的属性state.就可以通过`this.state.xxx`获取
    
    所以我们只需要保证this永远指向该构造对象(组件)即可,所以我们一般不会通过function来创建函数(会使得this动态指向调用function的对象), 并且:  
    
    <b>React组件类的方法没有默认绑定this到组件实例,需要手动绑定。</b>
    
    所以就衍生出了绑定this的方法;常用的有四种,我们一般会使用在constructor里面bind
    

    //优先级最高
    constructor(props){
    super(props);

    this.handleEvent = this.handleEvent.bind(this)
    

    }

    这种和直接在构建事件中绑定很像对吧?
    
    ``` 原理虽然是一样的,但是性能却差了一大截.为什么?

    我们知道只要state值改变了,就会导致render重新渲染,如果直接在创建事件绑定,那每一次渲染的时候都需要重新绑定一次,会大大降低性能.相反,只要在构造的时候绑定,无论渲染多少次,绑定都还是一次

    此外还有比较常用的箭头函数绑定法和::绑定法
    前面也介绍了箭头函数this的知识,所以在React出现也是蛮高的

    handleEvent = () => {
        ...
    }
    
    <input onChange={this.handleEvent} />
    

    ::虽然也可以绑定this,但是因为不能传参数,所以不经常使用

    handleEvent = () => {
        ...
    }
    
    <input onChange={::this.handleEvent} />
    
  • 相关阅读:
    Codeforces Round #604(Div. 2,
    简单的三层框架以及使用dbutils进行数据库操作(入门)
    DBUtil数据库工具封装
    GUI 中监听 文本框实时改变的实例
    java基础教程GUI
    Dao层通用化,Spring3.0+Hibernate3.3.2通用Dao层整合
    计算器代码
    记事本应用程序java源代码
    GUI
    dbutils开源项目用法
  • 原文地址:https://www.cnblogs.com/soyxiaobi/p/9737234.html
Copyright © 2020-2023  润新知