美文网首页
05:为什么React的构造函数里总是要bind(this)?

05:为什么React的构造函数里总是要bind(this)?

作者: 赛博剑仙_李玄器 | 来源:发表于2020-01-03 11:10 被阅读0次

在JavaScript中,以下两种写法是不等价的:

let obj = {
    tmp:'Yes!',
    testLog:function(){
        console.log(this.tmp);
    }
};

obj.testLog();      //方法一:此时为obj调用testLog函数,其中的this指向obj,所以结果为Yes

let tmpLog = obj.testLog;        //方法二
tmpLog();       //此时为window调用tmpLog函数,其中this指向window,但window没有定义tmp,所以结果为undefined

bind 方法确保了第二种写法与第一种写法相同。

看了好多博客都说是this丢失了指向,虽然可以这么理解。

但究其原因,我觉得只是因为在不同作用域里调用了同一个函数。而函数里面的this,由于指向不同外部环境从而产生了问题,this指向没丢,指的方向不同罢了。

bind() 方法创建一个新的函数,在 bind() 被调用时,该新函数的 this 指向 bind() 中的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

简单理解,当render里如果出现一个onClick={this.incrementAsync}
此时的步骤其实是

let incrementAsync = this.incrementAsync
onClick={ incrementAsync }

如果没有bind(this)将指向绑定到当前组件,此时的this.incrementAsync等于window.incrementAsync,而window里没有声明incrementAsync,所以会导致其值为undefined

import React, { Component } from 'react'

class Counter extends Component {
  constructor(props) {
    super(props);
    this.incrementAsync = this.incrementAsync.bind(this);   //bind()返回拥有指定this的原函数的拷贝,然后初始化赋值给左端
  }

  incrementAsync() {
    setTimeout(this.props.onIncrement, 1000)
  }

  render() {
    return (
      <p>
        <button onClick={this.incrementAsync}>  //如果没有constructor里的bind,该this指向window
          Increment async
        </button>
      </p>
    )
  }
}

如果你不喜欢在构造函数里用bind,那么你可以在回调中使用一个箭头函数:

import React, { Component } from 'react'

  incrementAsync() {
    setTimeout(this.props.onIncrement, 1000)
  }

  render() {
    return (
      <p>
        <button onClick={ (e) => this.incrementAsync(e) }>  
          Increment async
        </button>
      </p>
    )
  }
}

这个语法的问题是,每次 LoggingButton 渲染时都创建一个不同的回调。在多数情况下,没什么问题。然而,如果这个回调被作为 prop(属性) 传递给下级组件,这些组件可能需要额外的重复渲染。我们通常建议在构造函数中进行绑定,以避免这类性能问题。

相关文章

  • 05:为什么React的构造函数里总是要bind(this)?

    在JavaScript中,以下两种写法是不等价的: bind 方法确保了第二种写法与第一种写法相同。 看了好多博客...

  • react事件处理函数及事件

    为react元素添加事件处理函数的方法: 一、在类中有三种方法: 在构造函数中用bind 用箭头函数的方式 在回调...

  • React事件绑定

    1、在构造函数内使用bind绑定this 2、箭头函数绑定this 3、使用bind()绑定this 4、使用箭头...

  • JS模拟实现bind,call,apply

    call apply bind 简单实现 函数柯里化的实现 构造函数的实现 ES6实现 结合实现

  • react性能优化 不要再component的props中使用箭头函数或者bind,因为每次使用箭头函数和bind...

  • 函数绑定与函数柯里化

    用于创建已经设置好了一个或者多个参数的函数。创建柯里化函数的通用方式: 柯里化构造更为复杂的bind()函数:

  • super(props)

    为什么要调用super 这其实是JS的限制,而不是React。在构造函数中,如果要使用this就需要提前调用sup...

  • React学习笔记二-组件创建

    React中创建组件 第一种 - 创建组件的方式 使用构造函数来创建组件,如果要接收外界传递的数据,需要在构造函数...

  • 探究JavaScript中new操作以及__proto__与pt

    昨天看了大牛的这篇关于模拟bind函数实现的文章,深受启发。其中有一处涉及到关于bind方法返回的函数作为构造函数...

  • C++ 构造函数,类的成员变量

    c++ 05 构造函数无参构造函数有参构造函数 拷贝构造函数 浅拷贝 深拷贝 类的成员变量 四类特殊的成员变量

网友评论

      本文标题:05:为什么React的构造函数里总是要bind(this)?

      本文链接:https://www.haomeiwen.com/subject/ashzoctx.html