React中this指向丢失问题? 解决方法(经典面试题)

103 阅读1分钟

问题分析:

this指向undefined问题出现在: ①class组件中 ②在事件处理函数中

  1. this不会指向事件源对象---JSX=>React.createElement()=>创建的都是虚拟DOM对象
  2. this也不止像window---JSX=>'use strict',严格模式下函数中的this不指向window
  3. 严格模式下,全局函数中的this永远指向undefined
import React, { Component } from 'react'
export default class App extends Component {
  buyCount = 3
   f1() {  //等价于f1=function(){}
     console.log(this); //普通function中的this指向他们的调用者
     }
  render() {
    return (
      <>
        <button onClick={this.f1}>-</button>
        <input defaultValue={this.buyCount} />
        <button>+</button>
•      </>
•    )
  }
}

解决方案:

方案1:箭头函数(无法传参数)

f1=()={console.log(this)}

onClick={this.f1}

import React, { Component } from 'react'
export default class App extends Component {
  buyCount = 3
  f1 = () => {
    console.log(this);   //箭头函数不会修改this的指向,而会保留
  }
  render() {
    return (
      <>
        <button onClick={this.f1}>-</button>
        <input defaultValue={this.buyCount} />
        <button>+</button>
      </>
    )
  }
}

方案2:箭头函数(可以传参)

f1(形参){ console.log(this) }

onClick={ ()=>this.f1(实参) }

import React, { Component } from 'react'
export default class App extends Component {
  buyCount = 3
  f1(num) {  //等价于f1=function(){}
    console.log(num, this); //普通function中的this指向他们的调用者
  }
  render() {
    return (
      <>
        <button onClick={() => this.f1(888)}>-</button>
        <input defaultValue={this.buyCount} />
        <button>+</button>
​
      </>
    )
  }
}

方案3:使用bind

f1=()={console.log(this)}

onClick={this.f1.bind(this)}

import React, { Component } from 'react'
export default class App extends Component {
  buyCount = 3
  f1() {  //等价于f1=function(){}
    console.log(this); //普通function中的this指向他们的调用者
  }
  render() {
    return (
      <>
        <button onClick={this.f1.bind(this)}>-</button>
        <input defaultValue={this.buyCount} />
        <button>+</button>
      </>
    )
  }
}
​

方案4: 使用bind

constructor(){

super()

this.f1=this.f1.bind(this)

}

f1(){ log(this)}

onClick={this.f1}

import React, { Component } from 'react'
export default class App extends Component {
  buyCount = 3
  constructor() {
    // 子类构造方法第一句话永远是
    super() //调用父类的构造方法,在子类体内先构建一个父类对象
    console.log('一个app类型的对象被创建');
    // this.buyCount = 8 //构造方法内可以对数据重赋值
    this.f1 = this.f1.bind(this)
  }
  f1() {  //等价于f1=function(){}
    console.log(this); //普通function中的this指向他们的调用者
  }
  render() {
    return (
      <>
        <button onClick={this.f1}>-</button>
        <input defaultValue={this.buyCount} />
        <button onClick={this.f1}>+</button>
      </>
    )
  }
}