React类的自定义原型方法中的this指向为什么是undefined?如何解决?(绑定 this 的几种方式)

首先来看下类中定义的原型方法的this不同调用时的指向:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript">
        class Person{
            constructor(){
                console.log("Person类constructor中的this:");
                console.log(this);
            }

            speak(){
                console.log("Person类speak方法中的this:");
                console.log(this);
            }
        }

        const person1 = new Person(); // this:Person{}
        person1.speak(); // this:Person{}
        const s = person1.speak;
        s(); // this: undefined
        // 此处如果window.s()会报s不存在
    </script>
</body>
</html>

事件调用方法时方法中的this指向:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <Button onclick="hanleClick()">this指向</Button>
    <script type="text/javascript">
        function hanleClick(){
            console.log("this指向:");
            console.log(this);
        }

        // 当点击Button时,hanleClick中的this指向为window
    </script>
</body>
</html>

类中的方法默认开启了局部的严格模式,严格模式下this为undefined: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <Button onclick="hanleClick()">this指向</Button>
    <script type="text/javascript">
        function hanleClick(){
            "use strict"
            console.log("this指向:");
            console.log(this);
        }

        // 开启严格模式前:当点击Button时,hanleClick中的this指向为window
        // 开启严格模式后:当点击Button时,hanleClick中的this指向为undefined
    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script type="text/babel">
        class MyComponent extends React.Component{
            // 1、handleClick放在哪?MyComponent原型上,供MyComponent实例调用;
            // 2、handleClick是作为onClick的回调,所以不是通过实例调用的,是直接调用;
            // 3、类中的方法默认开启了局部的严格模式,严格模式下this为undefined(这个和Babel没关系)
            handleClick(){
                console.log("React类的自定义方法中的this为:");
                console.log(this); // 当点击h2标签时,this为undefined
            }

            render(){
                return <h2 onClick={this.handleClick}>我是类定义的组件</h2>;
            }
        }

        ReactDOM.render(<MyComponent/>, document.getElementById("app"));
    </script>
</body>
</html>

如何让自定义原型方法中的this指向为组件实例?

 一、在constructor中bind绑定组件的this:

class Button extends React.Component{
  constructor(pops){
    super();
    this.handleClick = this.handleClick.bind(this); // 将原型方法handleClick的this指向为实例对象,然后赋给实例方法handleClick,此时实例上和原型上都有handleClick方法
  }

  handleClick = () => {
    console.log("this is ", this);
  }

  render(){
    return (<button onClick={this.handleClick}>按钮</button>)
  }
}

二、方法使用时绑定 this:

class Button extends React.Component{
  constructor(props){
    super(props);
  }

  handleClick = () => {
    console.log("this is ", this);
  }

  render(){
    return (<button onClick={this.handleClick.bind(this)}>按钮</button>)
  }
}

ReactDOM.render(
  <Button/>,
  document.getElementById("app")
);

三、使用属性初始化语法:

class LoggingButton extends React.Component {
  // 这个语法确保了 `this` 绑定在  handleClick 中
  // 这里只是一个测试
  handleClick = () => {
    console.log('this is:', this);
  }
 
  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

四、在回调函数中使用 箭头函数:

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }
 
  render() {
    //  这个语法确保了 `this` 绑定在  handleClick 中
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}

五、函数传参:

<button onClick={this.函数名.bind(this, '我是参数')}>点我传递实参</button>
fune(x, e){
    ...
}

...


render(){
    return (<button onClick={e => {this.fune("我是实参", e)}}>点我传递实参</button>)
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值