React 事件处理

679 阅读2分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」。

这是React清风拂面系列第五篇,上一篇请看这里

React里面对事件处理和原生事件的处理方式大同小异。

  1. 监听具体某个事件
  2. 添加事件处理函数
export default function Button() {
  function onClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={onClick}>
      Click me
    </button>
  );
}

上面代码监听了click事件,React里面事件一般用驼峰写法,on+具体某个事件。

除了上面写法,事件处理函数函数直接内联在JSX里面

<button onClick={function handleClick() {
  alert('You clicked me!');
}}>

<button onClick={() => {
  alert('You clicked me!');
}}>

传递事件处理函数

这种情况发生比如请求时,请求组件会把返回的结果抛给调用方自己处理,或者其他情况。

function Button({ onClick, children }) {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
}

function PlayButton({ movieName }) {
  function handlePlayClick() {
    alert(`Playing ${movieName}!`);
  }

  return (
    <Button onClick={handlePlayClick}>
      Play "{movieName}"
    </Button>
  );
}

上面代码里面,Button组件的点击事件处理函数调用了props传过来的handlePlayClick,这样Button组件就不用关心具体应该怎么处理,完整代码

事件冒泡

export default function Toolbar() {
  return (
    <div className="Toolbar" onClick={() => {
      alert('You clicked on the toolbar!');
    }}>
      <button onClick={() => alert('Playing!')}>
        Play Movie
      </button>
      <button onClick={() => alert('Uploading!')}>
        Upload Image
      </button>
    </div>
  );
}

例子

完整源码这里

当你点击Play Moive 会弹2次。

这是因为js事件再冒泡阶段会从目标元素一直往上,所以当你点击Play Moive时,除了触发自己本身的事件处理函数,父元素div的事件处理函数也被触发了。

阻止事件冒泡

事件处理函数第一个参数为事件对象,一般用e表示,可以调用e.stopPropagation()来阻止冒泡

function Button({ onClick, children }) {
  return (
    <button onClick={e => {
      e.stopPropagation();
      onClick();
    }}>
      {children}
    </button>
  );
}

完整代码

捕获阶段处理

有时候需要在捕获阶段添加事件处理函数,可以在事件名后面添加Capture

<div onClickCapture={() => { /* this runs first */ }}>
  <button onClick={e => e.stopPropagation()} />
  <button onClick={e => e.stopPropagation()} />
</div>

阻止默认行为

比如阻止链接跳转或者表单提交,可以用e.preventDefault()

export default function Signup() {
  return (
    <form onSubmit={() => alert('Submitting!')}>
      <input />
      <button>Send</button>
    </form>
  );
}

提交之后,会刷新整个页面,代码

export default function Signup() {
  return (
    <form onSubmit={e => {
+     e.preventDefault();
      alert('Submitting!');
    }}>
      <input />
      <button>Send</button>
    </form>
  );
}

阻止了默认行为的发生,完整代码这里