react事件处理中的this

32次阅读

共计 1971 个字符,预计需要花费 5 分钟才能阅读完成。

当你使用 ES6 class 语法定义一个组件的时候,通常的做法是将事件处理函数声明为 class 中的方法。例如,下面的 Toggle 组件会渲染一个让用户切换开关状态的按钮:

<!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> 事件处理中 this</title>
  <script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
  <!-- <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://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script> 
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    class Toggle extends React.Component {constructor(props) {super(props)
        this.state = {isToggleOn: false}
      }

      handleClick() {console.log(this) // undefined
        this.setState((state, props) => ({isToggleOn: !state.isToggleOn})) 
        // 大括号外需要加小括号
        // 原因:因为箭头函数写法 ()=>{} 后面的大括号作为函数体,// 如果上面 (state, props) => {isToggleOn: !state.isToggleOn} 不加上 () 则大括号里面 isToggleOn: !state.isToggleOn 将作为函数体执行,明显里面内容不是执行语句。// 如果加上小括号,(state, props) => ({isToggleOn: !state.isToggleOn})的函数体就相当于返回一个 {isToggleOn: !state.isToggleOn} 对象
      }

      render() {
        return (<button onClick={this.handleClick}>
            {this.state.isToggleOn ? 'on' : 'off'}
          </button>
        )
      }
    }

    ReactDOM.render(
      <Toggle />,
      document.getElementById('root')
    )
  </script>
</body>
</html>

当浏览器执行上述脚本代码时会发生如下错误:

错误产生的原因是因为 onClick={this.handleClick} 仅仅传入了函数的引用,并没有绑定执行函数 this 指向,所以 this 值是 undefinedthis.setState 就找不到setState

既然没有绑定函数的 this 指向,我们有以下两种方式指定this

  • 1、使用 bind 绑定this
constructor(props) {super(props)
    this.state = {isToggleOn: false}
    this.handleClick = this.handleClick.bind(this)
}

或者

render() {
    return (<button onClick={this.handleClick.bind(this)}>
        {this.state.isToggleOn ? 'on' : 'off'}
      </button>
    )
}
  • 2、回调函数采用调用式
render() {
    return (<button onClick={() => this.handleClick()}>
        {this.state.isToggleOn ? 'on' : 'off'}
      </button>
    )
}

handleClick函数调用者是 this(Toggle 对象),所以函数内部this 也指向 Toggle 对象

正文完
 0