React@16.x(4)核心概念-事件,this 是 undefined 的问题。

1,使用

在 React 中绑定事件比较简单。来看下3种使用方式:

函数组件

export default function Button() {
  function handleClick() {
    alert('你点击了我!')
  }

  return <button onClick={handleClick}>点我</button>
}

或内联事件处理函数:

export default function Button() {
  return (
    <>
      <button
        onClick={function handleClick() {
          alert('你点击了我!')
        }}
      >
        点我
      </button>
      <button
        onClick={() => {
          alert('你点击了我2!')
        }}
      >
        点我2
      </button>
    </>
  )
}

类组件

import React, { Component } from 'react'

export default class Button extends Component {
  handleClick() {
    alert('你点击了我!')
  }

  render() {
    return <button onClick={this.handleClick}>点我</button>
  }
}

内联事件处理函数,写法一致。

2,注意事项

  1. React 中内置的组件(HTML标签)的事件处理函数,仅支持浏览器事件名称
    换句话说,这些事件处理函数也算是标准的 DOM 属性,所以支持。

  2. 惯例的命名方式为【handle + 事件名】。比如 onClick={handleClick}onMouseEnter={handleMouseEnter} 等。

3,类组件 this 指向问题

在类组件中定义的事件处理函数,内部的 this 指向会有问题。没有做特殊处理的话,this 将指向 undefined

举例:

import React, { Component } from 'react'
import ReactDOM from 'react-dom'

class Button extends Component {
  handleClick() {
    console.log('this-click', this) // undefined
  }

  render() {
    console.log('this-render', this) // 组件实例
    return (
      <button onClick={this.handleClick}>点我</button>
    )
  }
}

ReactDOM.render(<Button />, document.getElementById('root'))

原理

在类中定义的方法是在原型上。默认情况下,在调用时没有指定 this ,那么方法内的 this 将被置为 undefined参考)。

不是全局对象 window 的原因是:class 体内部的代码总是在严格模式下执行

所以,当作为事件处理函数调用时,onClick 对应的是一个回调函数,也就是 this.handleClick 是方法的引用,此时并没有指定 this 值,所以内部的 thisundefined

类似如下效果:

'use strict'
const obj = {
  name: '下雪天的夏风',
  foo: function () {
    console.log(this.name)
  }
}
const bar = obj.foo
bar() // Uncaught TypeError: Cannot read properties of undefined (reading 'name')

render 方法中,this 指向组件实例是因为:在ReactDOM.render执行的时候,会new一个实例对象来调用render方法,实例直接调用时,this 自然指向实例自身。

解决

实现:事件处理函数的 this 指向实例对象。

1,bind

class Button extends Component {
  constructor(props) {
    super(props);
    // this 就是实例对象
    this.handleClick = this.handleClick.bind(this);
  }
}

2,箭头函数

MDN参考

在这里插入图片描述

换句话说,箭头函数在定义时,this 的值已经确定了(会捕获其所在上下文的 this 值)。而不像普通函数那样在调用时才能决定 this 的指向。

箭头函数体中的 this 将正确指向实例。

class Button extends Component {
  handleClick = () => {
    console.log("this-click", this);
  };
}

3,内联函数

class Button extends Component {
  render() {
    return (
      <button
        onClick={() => {
          console.log("this-click", this);
        }}
      >
        点我
      </button>
    );
  }
}

以上。

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下雪天的夏风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值