react中类组件this丢失及解决方法

ES6中的class

1. class中的this
class Point {
  constructor(x, y) {
    this.x = x // 1. this指向实例
    this.y = y
  }

  toString() {
    // 2. 类中的方法都定义在原型上,constructor也是一个方法
    return '(' + this.x + ', ' + this.y + ')'
  }
}

var point = new Point(2, 3)
point.toString() // (2, 3)
// 3. 因为this指向实例,x,y直接是定义在this对象上,所以x,y都是实例对象
//    自身的属性,而toString则是原型对象的属性,因为定义在Point类上
2. class中的set,get
class MyClass {
  constructor() {
    // ...
  }
  get prop() {
    return 'getter';
  }
  set prop(value) {
    console.log('setter: '+value);
  }
}

let inst = new MyClass();
inst.prop = 123;
// setter: 123
inst.prop
// 'getter'

注意:

  1. class中默认严格模式

class中的this指向

类的方法内部如果含有this,它默认指向类的实例

class Logger {
  printName(name = 'there') {
    this.print(`Hello ${name}`);
  }
  print(text) {
    console.log(text);
  }
}

const logger = new Logger();
const { printName } = logger;
printName(); // TypeError: Cannot read property 'print' of undefined

this是指向实例的,但是从logger中解构出printName方法后,单独执行,此时this指向调用该方法时所运行的环境,由于class内部是严格模式,所以this实际指向的是undefined

解决方案一:

class Logger {
  constructor() {
    this.printName = this.printName.bind(this);
  }
  // ...
}
// 在constructor里进行this绑定后,实例本身就有printName方法了,不再是从原型链上寻找,且this指向实例本身

解决方案二:

class Obj {
  constructor() {
    this.getThis = () => this;
  }
}

const myObj = new Obj();
myObj.getThis() === myObj // true

箭头函数内部的this总是指向定义时所在的对象。上面代码中,箭头函数位于构造函数内部,它的定义生效的时候,是在构造函数执行的时候。这时,箭头函数所在的运行环境,肯定是实例对象,所以this会总是指向实例对象。

测试

代码1:

// 使用 ES6 的 class 语法
class Cat {
 sayThis () {
 console.log(this); // 这里的 `this` 指向谁?
  }
 exec (cb) {
 cb();
  }
 render () {
 this.exec(this.sayThis);
  }
}

const tom = new Cat();
tom.render(); // 输出结果是什么?

代码2:

const jerry = {
 sayThis: function () {
 console.log(this); // 这里的 `this` 指向谁?
  },

 exec: function (cb) {
 cb();
  },

 render: function () {
 this.exec(this.sayThis);
  },
}

jerry.render();

答案

React中的class

react类组件中的this丢失啦!
场景1:

import React, { Component } from 'react'
export default class App3 extends Component {
    constructor(props){
        super(props)
            this.state = {
                num:1
            }
        }
    
  render() {
    return (
      <>
        <p>数字为:{this.state.num}</p>
        {/* <button onClick={()=>{this.setState({num:this.state.num+1})}}>累加1</button> */}
        <button onClick={this.addNum}>累加2</button>
      </>
    )
  }

  addNum(){
    this.setState({num:this.state.num+1})
  }
}

原因:由于点击时调用的是onClick,而onClick是Dom中的行为,this指向onClick调用的环境,所以丢失了

解决方法

import React, { Component } from 'react'

export default class App3 extends Component {

    constructor(props){
        super(props)
            this.state = {
                num:1
            }
            // this.addNum = this.addNum.bind(this) //累加3
        }
    
  render() {
    return (
      <>
        <p>数字为:{this.state.num}</p>
        {/* <button onClick={()=>{this.setState({num:this.state.num+1})}}>累加1</button> */}
        {/* <button onClick={this.addNum.bind(this)}>累加2</button> */}
        {/* <button onClick={this.addNum}>累加3</button> */}
          <button onClick={()=>{this.addNum()}}>累加4</button>
      </>
    )
  }

  addNum(){
    this.setState({num:this.state.num+1})
  }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值