React 中的响应时间详解

使用 React 可以在 JSX 中添加 事件处理函数。其中事件处理函数为自定义函数,它将在响应交互(如点击、悬停、表单输入框获得焦点等)时触发。

添加事件处理函数

如需添加一个事件处理函数,你需要先定义一个函数,然后 将其作为 prop 传入 合适的 JSX 标签。例如,这里有一个没绑定任何事件的按钮:

复制代码
export default function Button() {
  return (
    <button>
      未绑定任何事件
    </button>
  );
}

按照如下三个步骤,即可让它在用户点击时显示消息:

  1. Button 组件 内部 声明一个名为 handleClick 的函数。

  2. 实现函数内部的逻辑(使用 alert 来显示消息)。

  3. 添加 onClick={handleClick}<button> JSX 中。

    export default function Button() {
    function handleClick() {
    alert('你点击了我!');
    }

    return (
    <button onClick={handleClick}>
    点我
    </button>
    );
    }

你可以定义 handleClick 函数然后 将其作为 prop 传入 <button>。其中 handleClick 是一个 事件处理函数 。事件处理函数有如下特点:

  • 通常在你的组件 内部 定义。
  • 名称以 handle 开头,后跟事件名称。

按照惯例,通常将事件处理程序命名为 handle,后接事件名。你会经常看到 onClick={handleClick}onMouseEnter={handleMouseEnter} 等。

或者,你也可以在 JSX 中定义一个内联的事件处理函数:

复制代码

<button onClick={function handleClick() {

alert('你点击了我!');

}}>

或者,直接使用更为简洁箭头函数:

复制代码

<button onClick={() => {

alert('你点击了我!');

}}>

以上所有方式都是等效的。当函数体较短时,内联事件处理函数会很方便。

陷阱

传递给事件处理函数的函数应直接传递,而非调用。例如:

传递一个函数(正确) 调用一个函数(错误)
<button onClick={handleClick}> <button onClick={handleClick()}>

区别很微妙。在第一个示例中,handleClick 函数作为 onClick 事件处理函数传递。这会让 React 记住它,并且只在用户点击按钮时调用你的函数。

在第二个示例中,handleClick() 中最后的 () 会在 渲染 过程中 立即 触发函数,即使没有任何点击。这是因为在 JSX { 和 } 之间的 JavaScript 会立即执行。

当你编写内联代码时,同样的陷阱可能会以不同的方式出现:

传递一个函数(正确) 调用一个函数(错误)
<button onClick={() => alert('...')}> <button onClick={alert('...')}>

如果按如下方式传递内联代码,并不会在点击时触发,而是会在每次组件渲染时触发:

复制代码

// 这个 alert 在组件渲染时触发,而不是点击时触发!

<button onClick={alert('你点击了我!')}>

如果你想要定义内联事件处理函数,请将其包装在匿名函数中,如下所示:

复制代码

<button onClick={() => alert('你点击了我!')}>

这里创建了一个稍后调用的函数,而不会在每次渲染时执行其内部代码。

在这两种情况下,你都应该传递一个函数:

  • <button onClick={handleClick}> 传递了 handleClick 函数。
  • <button onClick={() => alert('...')}> 传递了 () => alert('...') 函数。

在事件处理函数中读取 props

由于事件处理函数声明于组件内部,因此它们可以直接访问组件的 props。示例中的按钮,当点击时会弹出带有 message prop 的 alert:

复制代码
function AlertButton({ message, children }) {
  return (
    <button onClick={() => alert(message)}>
      {children}
    </button>
  );
}

export default function Toolbar() {
  return (
    <div>
      <AlertButton message="正在播放!">
        播放电影
      </AlertButton>
      <AlertButton message="正在上传!">
        上传图片
      </AlertButton>
    </div>
  );
}

此处有两个按钮,会展示不同的消息。你可以尝试更改传递给它们的消息。

将事件处理函数作为 props 传递

通常,我们会在父组件中定义子组件的事件处理函数。比如:置于不同位置的 Button 组件,可能最终执行的功能也不同 ------ 也许是播放电影,也许是上传图片。

为此,将组件从父组件接收的 prop 作为事件处理函数传递,如下所示:

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

function PlayButton({ movieName }) {
  function handlePlayClick() {
    alert(`正在播放 ${movieName}!`);
  }

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

function UploadButton() {
  return (
    <Button onClick={() => alert('正在上传!')}>
      上传图片
    </Button>
  );
}

export default function Toolbar() {
  return (
    <div>
      <PlayButton movieName="魔女宅急便" />
      <UploadButton />
    </div>
  );
}

示例中,Toolbar 组件渲染了一个 PlayButton 组件和 UploadButton 组件:

  • PlayButtonhandlePlayClick 作为 onClick prop 传入 Button 组件内部。
  • UploadButton() => alert('正在上传!') 作为 onClick prop 传入 Button 组件内部。

最后,你的 Button 组件接收一个名为 onClick 的 prop。它直接将这个 prop 以 onClick={onClick} 方式传递给浏览器内置的 <button>。当点击按钮时,React 会调用传入的函数。

如果你遵循某个 设计系统 时,按钮之类的组件通常会包含样式,但不会指定行为。而 PlayButtonUploadButton 之类的组件则会向下传递事件处理函数。

命名事件处理函数 prop

内置组件(<button><div>)仅支持 浏览器事件名称,例如 onClick。但是,当你构建自己的组件时,你可以按你个人喜好命名事件处理函数的 prop。

按照惯例,事件处理函数 props 应该以 on 开头,后跟一个大写字母。

例如,Button 组件的 onClick prop 本来也可以被命名为 onSmash

复制代码
function Button({ onSmash, children }) {
  return (
    <button onClick={onSmash}>
      {children}
    </button>
  );
}

export default function App() {
  return (
    <div>
      <Button onSmash={() => alert('正在播放!')}>
        播放电影
      </Button>
      <Button onSmash={() => alert('正在上传!')}>
        上传图片
      </Button>
    </div>
  );
}

上述示例中,<button onClick={onSmash}> 代表浏览器内置的 <button>(小写)仍然需要使用 onClick prop,而自定义的 Button 组件接收到的 prop 名称可由你决定!

当你的组件支持多种交互时,你可以根据不同的应用程序命名事件处理函数 prop。例如,一个 Toolbar 组件接收 onPlayMovieonUploadImage 两个事件处理函数:

复制代码
export default function App() {
  return (
    <Toolbar
      onPlayMovie={() => alert('正在播放!')}
      onUploadImage={() => alert('正在上传!')}
    />
  );
}

function Toolbar({ onPlayMovie, onUploadImage }) {
  return (
    <div>
      <Button onClick={onPlayMovie}>
        播放电影
      </Button>
      <Button onClick={onUploadImage}>
        上传图片
      </Button>
    </div>
  );
}

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

请注意,App 组件并不需要知道 Toolbar 将会对 onPlayMovieonUploadImage什么 。上述示例是 Toolbar 的实现细节。其中,Toolbar 将它们作为 onClick 处理函数传递给了 Button 组件,其实还可以通过键盘快捷键来触发它们。根据应用程序特定的交互方式(如 onPlayMovie)来命名 prop ,可以让你灵活地更改以后使用它们的方式。

相关推荐
一斤代码2 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子2 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年2 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子2 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina2 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路3 小时前
React--Fiber 架构
前端·react.js·架构
coderlin_3 小时前
BI布局拖拽 (1) 深入react-gird-layout源码
android·javascript·react.js
甜瓜看代码3 小时前
1.
react.js·node.js·angular.js
伍哥的传说4 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409194 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app