this在事件处理中的绑定方式

283 阅读1分钟

对于事件处理,react提供了一系列的属性。解决方案几乎和标准的DOM一样,但也有不同的地方,比如:驼峰式命名。


通常处理事件的写法


export default class App extend React.Component {
 render() {
    return (
      <button onClick={ this.handleButtonClick }>
        click me
      </button>
    );
  }
  handleButtonClick() {
    console.log('Button is clicked');
  }
}

存在问题

但这样写 会有一个问题,就是上下文不一致,handleButtonClick函数里通过this来获取 App组件的引用,会报错;

handleButtonClick() {
    console.log(`Button is clicked inside ${ this.state.num }`);
    // 导致
    // Uncaught TypeError: Cannot read property 'state' of null
  }


解决方案

1、利用bind 来绑定this

tips:bind和call,apply区别;三种都可以改变函数执行的上下文,call和apply会立即执行该函数,bind不会立即执行

<button onClick={ this.handleButtonClick.bind(this) }>
  click me

2、利用constructor

但是1中这样做,会导致当 button 一遍遍被渲染的时候,bind函数会一遍遍被调用;优化方式,利用constructor;

export default class App extends React.Component{
  constructor(props) {
    super(props);
    this.state = { num: 1 };
    this.buttonClick = this.handleButtonClick.bind(this);
  }

  handleButtonClick() {
    const { num } = this.state
    console.log(`Button is clicked inside ${ num }`);
    this.setState({num: num+1 })
  }
  render() {
     return (
       <button onClick={ this.buttonClick }>
         click me {this.state.num}
       </button>
     );
   }

3、箭头函数

export default class App extends React.Component{
  constructor(props) {
    super(props);
    this.state = { num: 1 };
  }

  buttonClick = () => {
    const { num } = this.state
    console.log(`Button is clicked inside ${ num }`);
    this.setState({num: num+1 })
  }
  render() {
     return (
       <button onClick={ this.buttonClick }>
         click me {this.state.num}
       </button>
     );
   }
 }


tips:箭头函数不能用new。不能使用arguments(火狐36可以)

var fn1 = () => {console.log(arguments)}
fn1(11) // Uncaught ReferenceError: arguments is not defined

var fn2 = function(){console.log(arguments)}
fn2(22) // Arguments [22, callee: ƒ, Symbol(Symbol.iterator): ƒ]