### 彪哥

爱好前端

- 核心概念

  - JSX简介
  - 元素渲染
  - 组件&Props
  - State&生命周期
  - 事件处理
    - 与传统HTML绑定事件的区别
      - 阻止默认事件 (合成事件对象)
    - 绑定事件的方式
      - 事件命名规范
    - 向事件处理程序传递参数
  - 条件渲染
  - 列表&Key
  - 表单
  - 状态提升 (共享状态)
  - 组合vs继承
  - React哲学

- 高级指引

- Hook

- 案例演示

- 《React》笔记
- 核心概念

heBody
2021-03-24
目录

# 事件处理

# # 05. 事件处理

## # 与传统HTML绑定事件的区别

传统的 HTML：

    <button onclick="activateLasers()">
      Activate Lasers
    </button>

1
2
3

在 React 中略微不同：

    // 1.事件名为小驼峰； 2.传入函数以大括号包裹函数名形式
    <button onClick={activateLasers}>
      Activate Lasers
    </button>

1
2
3
4

- React 事件的命名采用小驼峰式（camelCase），而不是纯小写。
- 使用 JSX 语法时你需要传入一个函数作为事件处理函数，而不是一个字符串。

### # 阻止默认事件 (合成事件对象)

在 React 中，你需要这样阻止默认事件：

    function ActionLink() {
      function handleClick(e) {
        e.preventDefault();
        console.log('The link was clicked.');
      }

      return (
        <a href="#" onClick={handleClick}>
          Click me
        </a>
      );
    }

1
2
3
4
5
6
7
8
9
10
11
12

在这里，`e` 是一个合成事件。React 根据 W3C 规范
(opens new window)来定义这些合成事件，所以你不需要担心跨浏览器的兼容性问题。React 事件与原生事件不完全相同。如果想了解更多，请查看 `SyntheticEvent`
(opens new window) 参考指南。

## # 绑定事件的方式

使用 React 时，你一般不需要使用 `addEventListener` 为已创建的 DOM 元素添加监听器。事实上，你只需要在该元素初始渲染的时候添加监听器即可。

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

    class Toggle extends React.Component {
      constructor(props){
        super(props)
        this.state = {isToggleOn: true};

        // 为了在回调中使用 `this`，这个绑定是必不可少的
        this.handleClick = this.handleClick.bind(this)；
      }

      hadleClick(){
        this.setState(state => ({
          isToggleOn: !state.isToggleOn
        }));
      }

      render(){
        return(
          // 为了能在这里使用 this.handleClick调用方法，因此需要在构造函数内添加handleChick属性指向回调方法 ？
        	<button onClick={this.handleClick}>
            {this.state.isToggleOn ? 'ON' : 'OFF'}
          </button>
        )
      }
    }

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

你必须谨慎对待 JSX 回调函数中的 `this`，在 JavaScript 中，class 的方法默认不会绑定
(opens new window) `this`。如果你忘记绑定 `this.handleClick` 并把它传入了 `onClick`，当你调用这个函数的时候 `this` 的值为 `undefined`。

这并不是 React 特有的行为；这其实与 JavaScript 函数工作原理
(opens new window)有关。通常情况下，如果你没有在方法后面添加 `()`，例如 `onClick={this.handleClick}`，你应该为这个方法绑定 `this`。

如果觉得使用 `bind` 很麻烦，这里有两种方式可以解决。如果你正在使用实验性的 public class fields 语法
(opens new window)，你可以使用 class fields 正确的绑定回调函数：

    class LoggingButton extends React.Component {
      // 此语法确保 `handleClick` 内的 `this` 已被绑定。
      // 注意: 这是 *实验性* 语法。
      handleClick = () => {
        console.log('this is:', this);
      }
      render() {
        return (
          <button onClick={this.handleClick}>
            Click me
          </button>
        );
      }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14

Create React App
(opens new window) 默认启用此语法。

如果你没有使用 class fields 语法，你可以在回调中使用箭头函数
(opens new window)：

    class LoggingButton extends React.Component {
      handleClick() {
        console.log('this is:', this);
      }

      render() {
        // 此语法确保 `handleClick` 内的 `this` 已被绑定。
        return (
          <button onClick={() => this.handleClick()}>
            Click me
          </button>
        );
      }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14

此语法问题在于每次渲染 `LoggingButton` 时都会创建不同的回调函数。在大多数情况下，这没什么问题，但如果该回调函数作为 prop 传入子组件时，这些组件可能会进行额外的重新渲染。我们通常建议在构造器中绑定或使用 class fields 语法来避免这类性能问题。

### # 事件命名规范

在 React 中，有一个命名规范，通常会将代表事件的监听 prop 命名为 `on[Event]`，将处理事件的监听方法命名为 `handle[Event]` 这样的格式。

## # 向事件处理程序传递参数

在循环中，通常我们会为事件处理函数传递额外的参数。例如，若 `id` 是你要删除那一行的 ID，以下两种方式都可以向事件处理函数传递参数：

    <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
    <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

1
2

上述两种方式是等价的，分别通过箭头函数
(opens new window)和 `Function.prototype.bind`
(opens new window) 来实现。

在这两种情况下，React 的事件对象 `e` 会被作为第二个参数传递。如果通过箭头函数的方式，事件对象必须显式的进行传递，而通过 `bind` 的方式，事件对象以及更多的参数将会被隐式的进行传递。

编辑
(opens new window)
#React
上次更新: 2022/12/14, 19:36:42
State&生命周期
条件渲染

← State&生命周期 条件渲染→

最近更新

  01
Git修改分支名
08-11

  02
CSS给table的tbody添加滚动条
06-29

  03
我做了一个手写春联小网页，祝大家虎年暴富 原创
01-28

更多文章>

Copyright © 2016-2022 Hesb | MIT License

- 跟随系统
- 浅色模式
- 深色模式
- 阅读模式