四种方法改变react组件中方法this的指向

改变react组件中方法的指向

在react的class中(一般用class作为构造函数的语法糖),我们经常会遇到引用方法的情况,比如下面这个demo:

  • 他的效果是,当我点击按钮,控制台输出’这个是信息’
  class App extends React.Component {
    
    
      constructor(){
    
    
          super()
          this.state = {
    
    
          }
        }
      render(){
    
    
        return(
          <div>
            <button onClick={
    
    this.showMsg}>按钮</button>
          </div>
        )
      }
      showMsg(){
    
    
        console.log('这个是信息');
      }
    }

但是,当我们要使用showMsg()这个方法中的this时,这个this指的是什么呢?

  • 尝试一下,结果打印的是undefined

那么问题来了,如何将上面showMsg()这个方法的this指向App这个对象,而不是undefined呢?

有四种方法可以将方法中的this指向它所在的组件对象

第一种,简单暴力,直接使用api bind改变this的指向

  • 使用bind()api来改变showMsg的this,下面的事件中,两个this都是方法所在的组件对象
  • 因此将showMsg原本的this改成了render函数的this,即App这个组件对象
  • 但是当我们有很多按钮时,这么写每个事件都需要改变一次this,太麻烦了,有没有其他办法呢?
 <button onClick={
    
    this.showMsg.bind(this)}>改变showMsg指向的第一种方法</button>

在这里插入图片描述

  • 下面的代码,每次都要手动绑定一次,虽然可以实现需求,但是太麻烦了
 render(){
    
    
        return(
          <div>
            <button onClick={
    
    this.showMsg}>按钮</button>
            <button onClick={
    
    this.showMsg.bind(this)}>改变showMsg指向的第一种方法</button>
            <button onClick={
    
    this.showMsg.bind(this)}>改变showMsg指向的第一种方法</button>
            <button onClick={
    
    this.showMsg.bind(this)}>改变showMsg指向的第一种方法</button>
            <button onClick={
    
    this.showMsg.bind(this)}>改变showMsg指向的第一种方法</button>
            <button onClick={
    
    this.showMsg.bind(this)}>改变showMsg指向的第一种方法</button>
          </div>
        )

第二种,在第一种的基础上,将重复的代码合成一个

  • 原理,既然我每次都要改变一次showMsgthis的指向,那么我能不能只写一次就改变他原本的this指向呢?
  • 下面是实现的代码,使用this.showMsg = this.showMsg.bind(this),直接将showMsg原本的this指向了组件对象
 class App extends React.Component {
    
    
      constructor(){
    
    
          super()
          this.state = {
    
    
          }
          this.showMsg = this.showMsg.bind(this)
        }
      render(){
    
    
        return(
          <div>
            <button onClick={
    
    this.showMsg}>按钮</button>
            <button onClick={
    
    this.showMsg}>改变showMsg指向的第二种方法</button>
            <button onClick={
    
    this.showMsg}>改变showMsg指向的第二种方法</button>
            <button onClick={
    
    this.showMsg}>改变showMsg指向的第二种方法</button>
            <button onClick={
    
    this.showMsg}>改变showMsg指向的第二种方法</button>
          </div>
        )
      }
      showMsg(){
    
    
        console.log(this);
      }
    }

第三种方法,既然showMsg本身的this指向的undefined,那么如果他本身没有this,那他的 this就会寻找它上级的作用域的对象

  • 所以我们可以使用箭头函数,箭头函数本身不绑定this,因此showMsg中的this只会向showMsg的上级作用域寻找对象,而showMsg上级作用域的对象就是组件对象.
  • 使用到了es6的特性
  • 下面是代码,可以看到依然是成功的
    class App extends React.Component {
    
    
      constructor(){
    
    
          super()
          this.state = {
    
    
          }
        }
      render(){
    
    
        return(
          <div>
            <button onClick={
    
    this.showMsg}>按钮</button>
            <button onClick={
    
    this.showMsg}>改变showMsg指向的第三种方法</button>
          </div>
        )
      }
      showMsg=()=>{
    
    
        console.log(this);
      }
    }

在这里插入图片描述

第四种方法,最推荐的方法,也是应该牢记经常使用的方法

  • 上次的博客记过,onClick后面的{}符号可以做很多事情,可以加减乘除,可以放方法,可以各种运算,那么可以现在{}中放一个方法
<button onClick={
    
    ()=>{
    
    console.log(this)}}>改变showMsg指向的第四种方法</button>
  • 这个时候可以看到,点击按钮,打印出来的this就是组件对象本身
    在这里插入图片描述
  • 所以可以看做是
onclick=()=>{
    
    
	console.log(this)
}
  • 那么替换一下,就可以写成下面这个样子
  • 当我点击按钮时,我执行箭头函数,而箭头函数中的showMsg方法会被执行
  • 还是利用到了箭头函数的tis指向,箭头函数不绑定this
  • 而且上面写了打印箭头函数this的例子,所以this.showMsg()中的this指向的是组件对象
<button onClick={
    
    ()=>{
    
    this.showMsg()}}>改变showMsg指向的第四种方法</button>

总结

就是这么理解

let x = {
    
    
  a(){
    
    
  console.log(this)
}
}

x.a()//this指向x
let b = x.a//函数a变成了b,b的指向是window,react中指代onClick,指向undefined,已经不是原来那个a了
b()//输出的是window
let c = ()=>{
    
    x.a()}//引用原来那个a
c()//输出的是x

猜你喜欢

转载自blog.csdn.net/MS6324_ZAKU/article/details/114055183