react的事件处理为什么要bind this 改变this的指向?

react的事件处理会丢失this,所以需要绑定,为什么会丢失this?

首先来看摘自官方的一句话:

You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default.

  

这句话大概意思就是,你要小心jax回调函数里面的this,class方法默认是不会绑定它的

让我十分疑惑,在我的知识范围理解中,class是es6里面新增的方法,不就用来继承原有对象上的属性和方法创建新的对象吗?就是代替原来的构造函数的一种更清晰的方式,为什么就不会绑定this呢?

可是查阅了一些es6的文档,并不是这样的啊,和class方法没啥关系吧,为什么要它背锅呢?

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}> //这里调用的this也能拿到啊??
        {this.state.isToggleOn ? ‘ON‘ : ‘OFF‘} //这里的this为什么没问题?
      </button>
    );
  }
}

  

这是官网上的一段代码,如果是是因为class的关系,handleClick里面拿不到this,那为什么render里面能拿到this,所以和class根本没关系吧本来就能拿到,那问题出现在哪里,为什么拿不到?

先看看解决办法

第一种,在constructor里面用bind绑定this

constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

第二种,声明方法的时候使用箭头函数

  handleClick = () => {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

第三种,调用的时候使用箭头函数

render() {
    return (
      <button onClick={ () => { this.handleClick } }>
        {this.state.isToggleOn ? ‘ON‘ : ‘OFF‘}
      </button>
    );
  }

  这个时候我想起了原生dom绑定click的方法

<button onclick ="handleClick()">点我</button>

  

  两者比较,我发现了个区别,原生的绑定方法事件名后面多了个()
于是我尝试着在react里面的事件加一个()

render() {
    return (
      <button onClick={ this.handleClick() }>
        {this.state.isToggleOn ? ‘ON‘ : ‘OFF‘}
      </button>
    );
  }

就像上面这样,然后我发现,无论我怎么点,都不会触发这个方法了,再细心点,就发现,在渲染的时候,就调用了一次,而且仅此一次,再也不能调用了.

原因是jsx语法,渲染的时候会把{}里面包裹的代码先解析一遍,因为如果加了括号,直接就执行了里面的函数,就没有东西了,但是这个时候,this是可以拿到的

class App extends Component {
  handleClick(){
      console.log(this); //下面调用加了(),这个时候发现,this是可以拿到的
  }
  render() {
    return (
      <div className="App">
        <button onClick={this.handleClick()}>点我</button> //这里加了括号的
      </div>
    );
  }
}

  好像问题越来越明朗了,为啥会拿不到,和class没有关系,完全是因为react自己封装的东西,先会把{}里面的代码解析一遍,于是大概就是下面这种情况了

const obj = {
        num:1
    }
    obj.handleClick = function () {
        console.log(this);
    }
    console.log(eval(obj.handleClick ));  // f(){ console.log(this) } react对{}的解析
    (eval(obj.handleClick))() //onclick触发点击事件 这里输出this是window,所以就等于丢失了this指向

    console.log(eval(() => { obj.handleClick() }));  // () => { obj.handleClick() } react对{}的解析
    (eval(() => {obj.handleClick()}))() //onclick触发点击事件 这里输出this还是obj,所以this就保留了

  所以问题出在react对{}的解析会把this的指向解除了

原文地址:https://www.cnblogs.com/zhaohongcheng/p/11235679.html

时间: 2024-10-08 00:07:18

react的事件处理为什么要bind this 改变this的指向?的相关文章

改变this的指向

一.this 一般情况下,this是在运行时动态指定的,指向调用它的对象. 在箭头函数中,没有自己的this值,它的this值继承自父作用域,是词法作用域,在定义的时候就被指定了,之后也不变. 二.call.apply.bind的相同点 1.都是用来改变函数的this指向的,执行目标函数的时候把目标函数的this执向改一下,并不会改变原函数的指向 function fn() { console.log(this); } var obj = { a:[4,5,6], b:[7,8], }; fn.

react篇章-事件处理

<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>React 实例</title> <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script> <script src=&quo

React之事件处理

在react中,事件处理的写法和处理方式可能会和vue以及传统html有些不同. 一.事件名和默认行为阻止 事件名采用驼峰写法,并且方法名用大括号引入,而不是双引号: <button onClick={activateLasers}> Activate Lasers </button> 对于类似a标签的默认跳转事件: handleClick(e) { e.preventDefault(); console.log('The link was clicked.'); } return

React练习 5 :鼠标移入移出改变样式

需求:鼠标移入/移出div范围时,样式发生改变 import React,{useState,useEffect} from 'react'; import ReactDOM from 'react-dom'; import './index.css'; function ChangeStyle(){ const [isHover,setHover]=useState(false); return( <div id="div1" className={isHover ? 'hov

运行前端React框架出现node Error: bind EADDRINUSE null的解决方法

运行前端React代码时,出现这样的错误: node Error: bind EADDRINUSE null 后来发现端口号冲突,换个端口号后问题就可以解决了. 原文地址:https://www.cnblogs.com/zhujiqian/p/12545421.html

JavaScript中改变this的指向方法(call和apple)

1.方法定义 call方法:语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call 方法可以用来代替另一个对象调用一个方法.call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象. 如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj apply方法: 语法:apply([thisObj[,argArray]]) 定

12.10 改变this的指向

1.解决函数内this指向 1.可以在函数外提前声明变量_this/that=this 2.通过apply和call来修改函数内的this指向 (1)二者区别   用法是一样的,就是参数形式不一样    fn.call(obj,a,b)/fn.apply(obj,[a,b]) (2)二者代表的是将函数内的this换成obj之后把fn调用 3.bind修改函数内的this fn.bind(obj,a,b)只是替换了this但是不调用fn,返回的还是函数 fn.bind(obj,a,b)() 2.

函数中,对形参做不加var的全局溢出赋值,可改变形参所指向的实参的本身值

var formateNumArr = function(arr,defaultVal){    var a = [];    $.each(arr,function(i,v){        if(!isNaN(v)){            a.push(v);        }else{            a.push(defaultVal);            arr[i] = '';//对不合法数据进行清空处理        }    });    return a;}var

你知道多少this,new,bind,call,apply?那我告诉你

那么什么是this,new,bind,call,apply呢?这些你都用过吗?掌握这些内容都是基础中的基础了.如果你不了解,那还不赶快去复习复习,上网查阅资料啥的! 通过call,apply,bind可以改变this的指向,this指向一般指向它的调用者,默认挂载在window对象下.es6中的箭头函数中,this指向创建者,并非调用者. const func = function () { console.log(this); const func2 = function () { conso