[React 2021新书]106、方法和绑定

357 阅读4分钟

React新手村

方法

下面我们看看如何给组件添加方法。方法可以和submit, click, change等事件绑定。

React里的事件

注意,React改变了事件的大小写。文本on被添加到事件名称的前面。还有事件使用驼峰命名法,典型的React 事件命名为:

on

发生的情况是文本 on 被添加到事件名称之前。此外,大小写更改名称,以便事件名称大写。基本上把 React 中的事件想象成这样:

on<Event name>

下面列举一些常见的事件命名:

事件名React的命名
clickonClick
changeonChange
submitonSubmit

希望你明白了 :)

绑定事件&事件处理方法

通过设定可以绑定事件(React命名法)和方法,下面演示基于class组件的绑定实例:

<Component onClick={this.handler}>

基于class的组件和基于函数的组件看起来略有不同。让我们先介绍前者:

class Element extends React.Component {
  constructor(props) {
    super(props);
    this.clicked = this.clicked.bind(this);
  } 

  clicked() {
    console.log('clicked');
  }

  render() {
    return (
      <button onClick={this.clicked}></button>
    )
  }
}

注意:

  • 构造函数, 在构造函数中有一行代码绑定方法clickedthis,该功能有多种实现方式:

    this.clicked = this.clicked.bind(this);
    

    绑定方法clickedthis是必须的。当在组件内方法clicked()访问属性的时候,例如:

    clicked() {
     console.log(this.props.someAttribute);
    }
    

    如果绑定成功,会打印出 someAttribute的值,如果没有绑定就会报错。

  • 在 JSX中. 在JSX中,可以使用下面这种方式来完成绑定:

    <button onClick={this.clicked}></button>
    

    有了构造函数的绑定,我们才可以直接使用 this.linked, 否则this就没有linked这个方法。

Class组件还有另外两种的绑定方法

到目前为止,我们使用类似 handler.bind(this) 语句来绑定事件和方法,但看起来不太优雅,而且还需要为每个方法执行绑定操作。

有更好的方式吗? 实际上我们还有另外两种方式可供选择:

  • 使用匿名函数lambda调用. 在JSX表达式中插入箭头函数
  • 将方法声明为类中的一个字段

使用匿名函数调用

我们来看看如何在标签中使用箭头函数:

class Element extends React.Component {
  constructor() {
    super();
  }

  state = {
    str: 'test'
  }

  clicked(evt) {
    console.log('clicked ' + this.state.str);
  }

  render() {
    return (
      <button onClick={(evt) => this.clicked(evt)}></button>
    )
  }
}

我们把这一行找出来:

<button onClick={(evt) => this.clicked(evt)}></button>

看看和第一种写法比较有什么不同,这是第一种:

onClick={this.clicked}

这是使用箭头函数:

onClick={(evt) => this.clicked(evt)}

使用使用箭头函数后就不需要在构造函数里面绑定了。还有我们可以在使用箭头函数时传入事件参数evt给回调函数,除此之外还可以传其他的参数:

render() {
    return (
      <button onClick={(evt) => this.clicked(evt, 'left')}></button>
      <button onClick={(evt) => this.clicked(evt, 'right')}></button>
      <button onClick={(evt) => this.clicked(evt, 'top')}></button>
      <button onClick={(evt) => this.clicked(evt, 'down')}></button>
    )
  }

上例中传入 left, right, top, down四个不同的参数给绑定的函数。事件evt为第一个参数,自定义参数为第二个参数。

将方法声明为类中的一个字段

// 注意: 这是 实验性 语法。

下面我们再来演示一种方法:

class Element extends React.Component {

  constructor() {
    super();
    //this.clicked = this.clicked.bind(this);
  }

  state = {
    str: 'test'
  }

  clicked = () => {
    console.log('clicked ' + this.state.str);
  }

  render() {
    return (
      <button onClick={this.clicked}></button>
    )
  }
}

> 注意,该语法需要babel 配置支持classProperties,参照 Props

注意比较之前的方法声明方式,这是旧的:

clicked() {
  console.log('clicked ' + this.state.str);
}

这是新的:

clicked = () => {
  console.log('clicked ' + this.state.str);
}

这是在class中声明方法的首选方式。

函数组件绑定事件方法

在函数组件中绑定事件方法略有不同,我们不需要考虑 this

import React from 'react'

const AComponent = (props) => {
  function handler(evt) => {
    console.log('clicked'); 
  }

  return (
    <div>
      <button onClick={handler}></button>
    </div> 
  )
}
export default AComponent;

上例所示,在函数组件中绑定事件方法更简单。

案例

  1. 运行 git clone 克隆开始项目:

    git clone https://github.com/softchris/react-starter-project demo-methods
    cd demo-methods
    

    该开始项目基于教程使用webpack配置react项目

  2. 运行 npm install 命令安装依赖包:

    npm install
    
  3. src 目录添加 Methods.js 文件,并添加以下内容:

    import React from 'react';
    
    class Method extends React.Component {
       constructor(props) {
         super(props)
         this.state = {
           direction: ''
         }
       }
    
     changeDirection (evt, direction) {
       this.setState({
         direction
       })
     }
    
     render() {
         return (<React.Fragment>
           <div>Direction: {this.state.direction}</div>
           <div>
             <button onClick={(evt) => this.changeDirection(evt, 'Top')}>Top</button>
             <button onClick={(evt) => this.changeDirection(evt, 'Left')}>Left</button>
             <button onClick={(evt) => this.changeDirection(evt, 'Right')}>Right</button>
             <button onClick={(evt) => this.changeDirection(evt, 'Bottom')}>Bottom</button>
           </div>
         </React.Fragment>
         )
      }
    }
    
    export default Method;
    

    上例定义一个了class组件,将其中按钮点击onClick 事件绑定方法 changeDirection()。

  4. index.js 文件中添加一行引入:

    import Method from './Method';
    
  5. 找到以下代码 ReactDOM.render( 做如下的修改:

    ReactDOM.render(
      <Method />,
      document.getElementById('app')
    );
    
  6. 在终端运行项目 npm start:

    npm start
    
  7. 打开浏览器访问 **http://localhost:8080\**. 查看结果:

    在顶部看到方向状态。选择其中一个按钮,状态更新。

代码参考

👉 Check out this solution

小结

介绍如何给组件添加方法,再将方法绑定到事件。

  1. 在构造函数中绑定方法用于事件处理。
  2. 使用 lambda箭头函数,可以跳过绑定还可以将值传递给方法。