函数组件中的函数应该放在哪里?

2023-12-09

我正在尝试将这种酷<canvas>我找到的动画here到 React 可重用组件中。看起来该组件需要一个用于画布的父组件,以及用于画布的许多子组件function Ball().

出于性能原因,使Balls进入无状态组件,因为它们会很多。我不太熟悉制作无状态组件,并且想知道应该在哪里定义this.update() and this.draw函数定义在function Ball().

无状态组件的函数是在组件内部还是外部?换句话说,以下哪一个更好?

1:

const Ball = (props) => {
    const update = () => {
        ...
    }

    const draw = () => {
        ...
    }

    return (
       ...
    );
}

2:

function update() {
     ...
}

function draw() {
     ...
}

const Ball = (props) => {
    return (
       ...
    );
}

每种方法都有哪些优点和缺点?其中一种更适合像我这样的特定用例?


首先要注意的是无状态功能组件不能有方法:你不应该指望调用update or draw在渲染的Ball如果它是无状态的功能组件。

在大多数情况下,您应该在组件函数之外声明函数,这样您只需声明一次,并且始终重用相同的引用。当您在内部声明函数时,每次渲染组件时都会再次定义该函数。

在某些情况下,您需要在组件内部定义一个函数,例如,将其分配为事件处理程序,该事件处理程序根据组件的属性表现不同。但你仍然可以在外部定义函数Ball并将其与属性绑定,使代码更加简洁,并使update or draw可重用的功能:

// you can use update somewhere else
const update = (propX, a, b) => { ... };
    
const Ball = props => (
  <Something onClick={update.bind(null, props.x)} />
);

如果您正在使用hooks, 您可以使用useCallback确保该函数仅在其任何依赖项发生更改时才重新定义(props.x在这种情况下):

const Ball = props => {
  const onClick = useCallback((a, b) => {
    // do something with a, b and props.x
  }, [props.x]);

  return (
    <Something onClick={onClick} />
  );
}

This is 错误的方法:

const Ball = props => {
  function update(a, b) {
    // props.x is visible here
  }
    
  return (
    <Something onClick={update} />
  );
}

使用时useCallback,定义update函数在useCallback钩子本身或组件外部成为最重要的设计决策:您应该考虑是否要重用update和/或如果您需要访问组件闭包的范围,例如读/写状态。就我个人而言,我选择默认将其定义在组件内部,并仅在需要时才使其可重用,以防止从一开始就过度设计。最重要的是,重用应用程序逻辑最好使用更具体的钩子来完成,而将组件保留用于演示目的。使用钩子时在组件外部定义函数实际上取决于您希望应用程序逻辑与 React 解耦的程度。

Another 共同讨论 about useCallback是是否总是将它用于每个功能。也就是说,对待就像opt-in or 总是值得推荐的。我认为总是使用useCallback:我见过许多由于未将函数包装在中而导致的错误useCallback并且在任何情况下这样做都不会以任何方式影响性能或逻辑。在大多数情况下,您希望在依赖项不变的情况下保留引用,因此您可以使用函数本身作为其他效果、备忘录或回调的依赖项。在许多情况下,回调将作为道具传递给其他元素,如果您使用useCallback您不会更改道具(从而重新渲染)其他组件,无论其成本有多低。我见过在组件中声明了数千个函数,但没有一个使用useCallback会有任何不利的一面。另一方面,大多数函数没有被记住useCallback如果开发人员没有意识到不这样做的影响,最终将被更改为这样做,从而导致严重的错误或性能问题。从技术上来说使用会降低性能useCallback,就像您将创建和附加函数一样,但与您使用总是必须发生的函数的重新声明相比,它可以忽略不计useCallback与否以及 React 和 JavaScript 的总体足迹。因此,如果您确实担心对性能的影响useCallback与不使用它相比,你应该问自己 React 是否是适合这项工作的工具。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

函数组件中的函数应该放在哪里? 的相关文章

  • TypeError: props.render 不是一个函数(React hook 形式)

    我将方法作为我用react hook form制作的形式的道具传递 当从react hook form添加控制器时 它给了我 TypeError props render不是一个函数 我在网上找不到任何解决方案 因此感谢任何帮助 impor
  • 如何重定向到 instagram://user?username={username}

    我的 html 页面上有这个链接 可以在特定用户上打开 Instagram 应用程序 a href Link to Instagram Profile a 我一直在寻找自动运行 url instagram user username USE
  • 使用 useReducers 调度函数发送多个操作?

    使用时是否可以通过调度函数发送多个动作useReducer挂钩反应 我尝试向它传递一组操作 但这会引发未处理的运行时异常 明确地说 通常会有一个初始状态对象和一个减速器 如下所示 const initialState message1 nu
  • 使用 jQuery/JS 打开时使
    标签的内容具有动画效果

    我只想要 HTML5 的内容details标记为 滑行 动画打开 而不是仅仅弹出打开 立即出现 这可以用 jQuery Javascript 实现吗 Fiddle http jsfiddle net 9h4Hq HTML
  • 检查 JavaScript 字符串是否为 URL

    JavaScript 有没有办法检查字符串是否是 URL 正则表达式被排除在外 因为 URL 很可能是这样写的stackoverflow 也就是说它可能没有 com www or http 如果你想检查一个字符串是否是有效的 HTTP UR
  • Google App Engine:修改云运行环境

    我正在尝试部署一个使用自定义 Node js 服务器的 Next js 应用程序 我想将自定义构建变量注入应用程序 next config js const NODE ENV process env NODE ENV const envTy
  • 音频 blob 的 URL.createObjectURL 在 Firefox 中给出 TypeError

    我正在尝试从创建的音频 blob 创建对象 URLgetUserMedia 该代码在 Chrome 中可以运行 但在 Firefox 中存在问题 错误 当我打电话时stopAudioRecorder 它停在audio player src
  • 使用 KnockoutJs 映射插件进行递归模板化

    我正在尝试使用以下方法在树上进行递归模板化ko映射 插入 http knockoutjs com documentation plugins mapping html 但我无法渲染它 除非我定义separate每个级别的模板 在以下情况下
  • React - 无法读取未定义的属性[重复]

    这个问题在这里已经有答案了 通常 当我单击子组件中的菜单项时 它会调用 this handlesort 这是一个本地函数 处理排序从我的父组件中获取 onReorder 属性 onReorder 调用名为 reOrder 的本地函数 它设置
  • 表单计算器脚本基本价格未加载 OnLoad

    我的表单中有一个计算器来计算我的下拉选项选择 function select calculate on change calc input type checkbox calculate on click calc function cal
  • Firefox 书签探索未超过 Javascript 的第一级

    我已经编写了一些代码来探索我的 Firefox 书签 但我只获得了第一级书签 即我没有获得文件夹中的链接 e g 搜索引擎 雅虎网站 谷歌网站 在此示例中 我只能访问 Search engines 和 google com 不能访问 yah
  • Angular 2+ 安全性;保护服务器上的延迟加载模块

    我有一个 Angular 2 应用程序 用户可以在其中输入个人数据 该数据在应用程序的另一部分进行分析 该部分仅适用于具有特定权限的人员 问题是我们不想让未经授权的人知道how我们正在分析这些数据 因此 如果他们能够在应用程序中查看模板 那
  • Laravel 中只向登录用户显示按钮

    如果我以 John 身份登录 如何才能只显示 John 的红色按钮而不显示 Susan 的红色按钮 测试系统环境 Win10 Laravel5 4 Mysql5 7 19 table class table table responsive
  • 为 illustrator 导出脚本以保存为 web jpg

    任何人都可以帮我为 illustrator CC2017 编写一个脚本 将文件以 JPG 格式导出到网络 旧版 然后保存文件并关闭 我有 700 个文件 每个文件有 2 个画板 单击 文件 gt 导出 gt 另存为 Web 旧版 然后右键文
  • HTML 离线应用程序缓存,列出下载的文件

    作为我正在构建的离线 Web 应用程序的加载屏幕的一部分 使用缓存清单 http developer apple com library safari documentation iPhone Conceptual SafariJSData
  • 在 React 中实现 Google 登录错误 -

    我正在尝试在 React 中实现 google 登录 这是我的组件 import Fragment useEffect from react import GOOGLE CLIENT ID from some file const Goog
  • 模块构建失败(来自 ./node_modules/babel-loader/lib/index.js)Vue Js

    我从 GitHub 下载了一个我和我的朋友正在开发的项目 但是当我尝试运行时 npm run serve 我收到这个错误 src main js 中的错误 Module build failed from node modules babe
  • Javascript 纪元时间(以天为单位)

    我需要以天为单位的纪元时间 迄今为止 我已经看到过有关如何翻译它的帖子 但几天后就没有了 我对纪元时间很不好 我怎么能得到这个 我需要以天为单位的纪元时间 我将解释为您想要自纪元以来的天数 纪元本身是第 0 天 或第 1 天的开始 无论您如
  • JQuery 图像上传不适用于未来的活动

    我希望我的用户可以通过帖子上传图像 因此 每个回复表单都有一个上传表单 用户可以通过单击上传按钮上传图像 然后单击提交来提交帖子 现在我的上传表单可以上传第一个回复的图像 但第二个回复的上传不起作用 我的提交过程 Ajax 在 php 提交
  • 如何获取浏览器视口中当前显示的内容

    如何获取当前正在显示长文档的哪一部分的指示 例如 如果我的 html 包含 1 000 行 1 2 3 9991000 并且用户位于显示第 500 行的中间附近 那么我想得到 500 n501 n502 或类似的内容 显然 大多数场景都会比

随机推荐