为什么react中需要bind

为什么react中需要bind

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方法默认是不会绑定它的

第一种,在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的指向解除了

本文来自React答疑栏目,欢迎学习!

以上就是为什么react中需要bind的详细内容,更多请关注html中文网其它相关文章!

赞(0) 打赏
未经允许不得转载:html中文网首页 » React 答疑

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

前端开发相关广告投放 更专业 更精准

联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏