[ Day 17 ] React 中的事件处理

https://ithelp.ithome.com.tw/upload/images/20211002/20134153HlJA85ahvZ.png
结束了 React Hooks 的章节之後,今天要进入到网页互动少不了的事件处理部分了。 在 React.js 当中针对 DOM 事件处理的方式和原本 JavaScript 的写法上会有什麽差异呢?


撰写差异

一起来看看官网的范例,如果是采用 HTML 来撰写事件处理的方式:

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

我们可以在 HTML 当中使用使用事件处理的 onclick 方法,并赋予他对应处理的 Function 函式。

但如果是在 React.js 当中,我们就要改写成下面范例程序码:

<button onClick={activateLasers}>
  Activate Lasers
</button>

透过上面范例程序码可以发现 JSX 和原本 HTML 撰写不一样的地方:

  1. 处理事件的名称是采用 驼峰式命名( camelCase ) 的方式。
  2. 赋予该事件的值是一个 {} 包起来的 JavaScript Function

另外除了写法上的差异之外,其实 React.js 对於事件的处理是采用一层叫做 SyntheticEvent 合成事件的处理机制。

Synthetic Events

React.js 采用 W3C 标准所撰写的一个事件处理物件,具备了跨浏览器以及效能优化等功能所以能够用更简易的语法来处理事件的相关行为。

所以我们在处理某些事件的时候就需要采用 不同於原生事件( Native Event ) 的写法,下面就给大家看一个范例:

/* HTML 写法 */
<form onsubmit="console.log('You clicked submit.'); return false">
  <button type="submit">Submit</button>
</form>

在范例程序码中,我们要避免触发浏览器的预设行为:点击後开启新分页,这时可以使用 return false 加在 onsubmit 这个事件处理之後就会达到需要的效果。

但如果要在 React.js 中移除掉浏览器本身的预设行为的话,就要采用另一种的撰写方式:

function Form() {
  function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

在上面的 Function Component 中我们一定要使用 e.preventDefault() 这个方法来做阻挡该浏览器的行为,不能使用上面 Native Event 的写法。
要特别注意元件里面的 e 这个 event 并不是原本的 Native Event 而是上面提到的 Synthetic Event ,所以记得使用上会使有差异的。

备注:关於 e.preventDefault() 这个方法不熟悉的话,可以参考 Kuro 大大的这边文章:重新认识 JavaScript: Day 15 隐藏在 "事件" 之中的秘密


事件绑定和传值

事件处理方法的绑定

在官网当中还有特别提到,如果使用 Class 的元件在事件处理上是没有预先使用 bind 语法做好绑定的话,就会发生取值产生 undefined 的状况,这边我们就直接看范例:

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

    // 为了让 `this` 能在 callback 中被使用,这里的绑定是必要的:
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

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

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

这边使用官网的范例 CodePen,该范例想要实现监听按钮的点击事件然後变更按钮上方的文字是 ON 或是 OFF 。

在上方的范例中我们在 constructor() 中初始化资料并绑定在这个元件实体上,这样在 render() 回传的 JSX 当中才能确实的使用到该 handleClick() 的函式。

透过事件处理传递参数

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

在处理阵列资料或是回圈时,我们通常会需要传递额外的参数给事件处理的函式。因此在上面的范例中使用了箭头函式的第一行程序码需要带入 id 参数之外也必须将 event 第二个参数 e 一同写入,这样才能确实的传入。
但如果是采用第二行的 bind 绑定语法的话就不需要额外传递 event 的参数,因爲绑定过後的所有参数都会被确实的传递到该函式内。


React.js 中的 Event Handle 事件处理的一些简介和用法就先为大家介绍到这边了。这个章节会是我们写 React.js 开发时不可或缺的功能,大家可以多看几遍了解原理跟细节唷!
明天要跟大家介绍的是条件渲染,虽然我现在也还不知道那是什麽(?
那我们就下篇见ʘ‿ʘ


<<:  每日挑战,从Javascript面试题目了解一些你可能忽略的概念 - Day17

>>:  Day16【Web】网路攻击:连线劫持/Cookie 窃取

CPU反装与散热器外露

记得小大一在微积分课,老师讲到拓朴学的时候说到了一个故事,有人对囚犯说,你被关在监狱里面,囚犯却对这...

Day 16 - 研习计画起源与菜鸟业师面试学生篇

渐渐的掌握专案开发的技术以及与厂商洽谈的诀窍後,接着迎接了一个新的挑战是先前没有遇过的,那就是协助单...

Day 29

Vortex 现在我们有火焰了,但是呢如果今天我的火焰想要有点这种效果呢。 感觉有个台风在那里影响火...

[Day09] Storybook - What's a story and how to write

Story 是元件呈现状态的描述,开发者可以为每个元件攥写多个 Story,也就是说元件可能会因为不...

利用大数据分析预测MLB胜负(上)

本文将要介绍由Andrew Y. Cui撰写的《Forecasting Outcomes of Ma...