React 组件【2】

75 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

前言

React 组件【1】中已经详细介绍了什么是 React 组件,React 组件的创建方式,React 组件的事件处理以及 React 组件中最重要的 state 和 setState()等。 但是对于 React 组件的使用,我们还需要注意以下几点:

1. 简化代码

具体做法是从 JSX 中抽离事件处理程序

  • JSX 中掺杂过多 JS 逻辑代码,会显得非常混乱
  • 推荐:将逻辑抽离到单独的方法中,保证 JS 结构清晰

简化后的代码如下:

class App extends React.Component{
  state = {
    count: 10
  }

  handleClick(){
    this.setState({
      count: this.state.count + 1
    })
  }

  render(){
    return (
      <div>
        <span>计数器:{this.state.count}</span>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

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

运行代码,报错如下: c3a8e24a-e0b3-4c71-8f52-33e5ea5a9693.png

报错原因:事件处理程序中 this 的值为 undefined

希望:this 指向组件实例(render 方法中的 this 即为组件实例,因为 render 中用的是箭头函数,而箭头函数中没有 this,它就会去外部寻找,也就是 render,所以 this 指向的是 render 本身,如果将箭头函数改为 function 也会报错。)

由此我们可以继续引出下一点:如何解决事件绑定的 this 指向问题?

2. 事件绑定 this 指向

解决 this 指向的方法主要有以下几种:

2.1 箭头函数

  • 利用箭头函数自身不绑定 this 的特点
class App extends React.Component{
  state = {
    count: 10
  }

  handleClick(){
    console.log('事件处理程序中的this:',this)
    this.setState({
      count: this.state.count + 1
    })
  }

  render(){
    return (
      <div>
        <span>计数器:{this.state.count}</span>
        <button onClick={() => this.handleClick()}>+1</button>
      </div>
    )
  }
}

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

2.2 Function.prototype.bind()

  • 利用 ES5 中的 bind 方法,将事件处理程序中的 this 与组件实例绑定到一起
class App extends React.Component{
  constructor(){
    super()

    this.state = {
      count: 10
    }

    this.handleClick =this.handleClick.bind(this)
  }
  

  handleClick(){
    this.setState({
      count: this.state.count + 1
    })
  }

  render(){
    return (
      <div>
        <span>计数器:{this.state.count}</span>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

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

2.3 class 的实例方法(推荐)

  • 利用箭头函数形式的 class 实例方法
  • 注意:该语法是实验性语法,但是,由于 babel 的存在可以直接使用
class App extends React.Component{
  state = {
    count: 10
  }

  handleClick = () =>{
    console.log('事件处理程序中的this:',this)
    this.setState({
      count: this.state.count + 1
    })
  }

  render(){
    return (
      <div>
        <span>计数器:{this.state.count}</span>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

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