React:推荐箭头还是普通函数?

2023-11-24

在我觉得手动函数/对象绑定和范围相关问题很令人头痛之后,我开始使用箭头函数,但最近我开始知道使用普通函数(ES5)比箭头函数(ES6)更好。

我对这些功能的理解

React 中的正常功能:

  1. 手动绑定对象/函数,以便在函数内使用状态或道具并避免与作用域相关的问题
  2. 始终在构造函数中绑定对象/函数,但不直接在渲染中绑定对象/函数
  3. 如果您在构造函数中执行此操作,则 Webpack 仅在组件首次渲染时在 bundle.js 文件中创建一次新对象/函数
  4. 如果你直接在渲染中执行此操作,那么每次组件渲染和重新渲染时,Webpack 都会在 bundle.js 文件中创建一个新的对象/函数
  5. 如果不绑定,则无法访问状态或道具。您必须将当前对象分配给局部变量,否则 this.state 或 this.props 未定义

React 中的箭头函数:

  1. 无需在构造函数中绑定对象/函数,也无需渲染
  2. 您无需依赖当前对象的局部变量,即 let that = this;
  3. 您不会遇到范围问题,并且对象/函数绑定会自动进行

但我的疑问是,我听说建议使用普通函数并将其绑定在构造函数中,而不是使用箭头函数,因为每次组件渲染和重新渲染时,箭头函数都会在 Webpack bundle.js 中创建新的对象/函数。

这是真的?推荐哪一个?

该线程接受了答案React中箭头函数的正确使用说 —> 这取决于您到底在哪里使用箭头函数。如果在 render 方法中使用 Arrow 函数,那么每次调用 render 时都会创建一个新实例,就像 bind 的工作方式一样。

如果你觉得这是一个戏剧性的问题,我很抱歉,但这是我最大的疑问。请建议


周围有很多答案,但人们总是感到困惑。我知道这一点是因为不久前我曾经感到困惑。一段时间后,我掌握了这些概念。

  1. 手动绑定对象/函数以便使用状态或道具 在函数内部并避免与作用域相关的问题

不完全正确。您不需要绑定函数来使用状态或道具。您将函数绑定到this当你失去时this范围内的上下文。例如在回调函数中。

class App extends React.Component {
  state = {
    name: "foo",
  }
  aFunction() {
    console.log( this.state.name );
  }
  render() {
    return <div>{this.aFunction()}</div>;
  }
}

您不需要绑定您的函数,因为this指出你的班级,并且你不会失去它的背景。但是,如果您在回调中使用函数(例如按钮),则必须绑定它:

class App extends React.Component {
  state = {
    name: "foo",
  }
  aFunction() {
    console.log( this.state.name );
  }

  render() {
    return (
      <div>
        <button onClick={this.aFunction}>Click</button>
      </div>
    );
  }
}

这不起作用,因为你失去了上下文。现在,您需要以某种方式恢复它的上下文,对吗?好的,让我们看看如何做到这一点。首先,我想将它绑定在按钮回调中。

<button onClick={this.aFunction.bind(this)}>Click</button>

是的,这有效。但是,它将在每次渲染中重新创建。所以:

  1. 始终在构造函数中绑定对象/函数,但不直接在渲染中绑定对象/函数

是的。不要像我上面那样绑定它,而是在你的构造函数中进行。

  1. 如果您在构造函数中执行此操作,则 Webpack 仅在组件创建时在 bundle.js 文件中创建一次新对象/函数 第一次渲染

  2. 如果你直接在渲染中执行此操作,那么每次组件渲染时,Webpack 都会在 bundle.js 文件中创建一个新的对象/函数 并重新渲染

您在这里总结了我迄今为止试图解释的内容。但是,我想 Webpack 不是这样做的,而是你的应用程序。

  1. 如果不绑定,则无法访问状态或道具。您必须将当前对象分配给局部变量,否则 this.state 或 this.props 未定义

同样,如果您在类范围内使用函数,则不必绑定它。如果您在类之外使用此函数(例如按钮回调),则必须绑定它。这与以下无关state or props。这与使用有关this.

绑定的第二个选项是使用常规函数在构造函数中进行绑定,第三个选项是使用不绑定的箭头函数。

现在,箭头函数。

1.不需要在构造函数和渲染中绑定对象/函数

Yes.

  1. 您无需依赖当前对象的局部变量,即 let that = this;

Yes.

  1. 您不会遇到范围问题,并且对象/函数绑定会自动进行

Yes.

但我的疑问是我听说建议使用普通 函数并将其绑定在构造函数中,而不是使用箭头函数 因为箭头函数在 Webpack 中创建新的对象/函数 每次组件渲染和重新渲染时都会调用bundle.js。

就像大家说的那样,这取决于你在哪里使用它们。

render() {
    return (
        <div>
            <button onClick={() => this.aFunction()}>Click</button>
        </div>
    );
}

在这里,它将在每次渲染中重新创建。但如果您不需要向其传递任何参数,则可以通过引用来使用它。

render() {
    return (
        <div>
            <button onClick={this.aFunction}>Click</button>
        </div>
    );
}

这与前一个一样。所以,如果你看到一个()在您的渲染方法中,此函数会在每次渲染中重新创建。常规的还是箭头的,并不重要。如果您以某种方式调用它,那么您就是在重新创建它。这适用于渲染中的绑定,例如aFunction.bind(this). I see () there.

因此,通过引用使用函数可以避免此问题。现在,最大的问题是当我们需要一些论证时会发生什么?如果您使用箭头函数传递参数,请尝试更改您的逻辑。

但这真的那么重要吗?就像 @Eric Kim 所说,如果你确实需要的话,优化就是一个问题。这是一个一般性的建议,因为我从很多人那里听到过这个建议。但就我个人而言,如果函数会在每次渲染中重新创建,我会尽量避免使用它们。但同样,这完全是个人的。

怎样才能改变你的逻辑呢?您正在使用一个项目映射一个数组并创建 一个按钮。在此按钮中,您使用的函数将项目名称传递给函数。

{
    items.map( item =>
        <button onClick={() => this.aFunction(item.name)}>Click</button>
    )
}

该函数将在每个项目的每次渲染中重新创建!所以,改变你的逻辑,创建一个单独的Item组件并映射它。通过item, aFunction作为道具。然后通过该组件中的处理函数使用您的函数。

const Item = ( props ) => {
    const handleClick = () => props.aFunction( props.item.name );
    return (
        <button onClick={handleClick}>Click</button>
    );
}

在这里,您正在使用onClick处理程序及其引用并调用您的实际函数。每次渲染中都不会重新创建任何函数。但是,缺点是您需要编写一个单独的组件和更多的代码。

大多数时候你都可以应用这个逻辑。也许会有一些你不能的例子,谁知道呢。所以决定权在你。

顺便说一下,@widged 在评论中给出的 Medium 帖子是关于这个问题的著名讨论。箭头函数真的比普通函数慢吗?是的。但多少钱呢?我想没那么多。此外,对于转译代码也是如此。将来当他们成为本地人时,他们将是更快的。

作为个人旁注。我一直在使用箭头函数,因为我喜欢它们。但前段时间在讨论中有人说

当我在类中看到箭头函数时,我想:“这个函数 正在此类之外使用/调用'。如果我看到一个普通的我 了解这个函数在类内部调用。

我真的很喜欢这种方法,现在如果我不需要在类之外调用我的函数,我将使用常规方法。

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

React:推荐箭头还是普通函数? 的相关文章

随机推荐

  • #java.lang.NoClassDefFoundError: org/apache/commons/digester/Digester

    我正进入 状态java lang NoClassDefFoundError org apache commons digester Digester错误 我被这个错误困扰了一个多月 我已经尝试了所有可用的 Digester 版本 并且还检查
  • 与 Tensorflow 中的常规 LSTMCell 相比,使用 CudnnLSTM 训练时的结果不同

    我正在 Python 中使用 Tensorflow 训练 LSTM 网络 并希望切换到 tf contrib cudnn rnn CudnnLSTM 以加快训练速度 我所做的被替换 cells tf nn rnn cell LSTMCell
  • Google 地图 -“除非更新 Google Play 服务,否则应用程序将无法运行”

    我只是想在这里运行简单的 Google 地图教程 https developers google com maps documentation android start 我正在 Nexus 4 上运行我的应用程序 并且收到带有 更新 按钮
  • Grafana划分2系列

    我试图将两个系列分开以获得它们的比率 例如 我的网站 a com b com c com 为 所有网站 他们每个人都有总部分数和发生错误的统计数据 我想将每个站点的错误 部分显示为条形错误 部分 其中部分 gt 错误到该站点的每个错误 在这
  • Python 正则表达式不工作

    我正在使用以下代码 downloadlink re findall http uploadir com u b str downloadhtml 但是 当我传递以下字符串时
  • 在 shell 脚本中调用 awk

    我有这个命令 如果直接在终端上运行 它可以正确执行 awk word print NR file txt head n 1 目的是找到单词所在行的行号 word 首先出现在file txt 但是当我把它放在脚本文件中时 它似乎不起作用 bi
  • 将 MediaWiki 站点迁移到 Windows Sharepoint Services Wiki

    有人找到了将 MediaWiki 页面迁移到 WSS Wiki 的方法吗 我们刚刚安装了 Sharepoint 2007 虽然它似乎满足了我们的需求 但它似乎不是 Microsoft 提供的任何用于将 MediaWiki 页面迁移到 WSS
  • 带有 Angular 的 ASP.NET MVC:- 页面刷新或重新加载会出现 404 错误

    角度版本 5 我正在使用 ASP NET MVC 开发一个新项目 并将 Angular 5 与其集成 该项目工作正常 只是页面刷新产生 404 页面未找到错误 每当我从浏览器点击刷新或重新加载页面时 都会出现 404 错误 我已经阅读了许多
  • 删除重复项,保留具有最大绝对值的条目

    假设我有四个样本 id 1 2 3 和 4 每个样本都有一个或多个测量值 gt a lt data frame id c 1 1 2 2 3 4 value c 1 2 3 4 5 6 gt a id value 1 1 1 2 1 2 3
  • ScreenUpdating = False 在 Excel 2013 和 2016 中失败

    我几年前开发的基于 Excel 的长期运行的高端应用程序在 Excel 2007 和 2010 中运行良好 在 Excel 2013 和 2016 中看起来就像业余时间 因为Application ScreenUpdating False不
  • Pandas 按组时间累积总和

    我有一个数据框 其中为每个 id 记录 1 个或多个事件 对于每个事件 都会记录 id 度量 x 和日期 像这样的东西 import pandas as pd import datetime as dt import numpy as np
  • 是否存在左关联前缀运算符或右关联后缀运算符之类的东西?

    这一页说 前缀运算符是usually右关联 后缀运算符左关联 强调我的 是否有左关联前缀运算符或右关联后缀运算符的真实示例 如果不是 那么假设的一个会是什么样子 以及如何解析它 使 左联想 和 右联想 的概念变得精确并不是特别容易 因为它们
  • Finalize方法中的异常[重复]

    这个问题在这里已经有答案了 可能的重复 方法终结和异常 垃圾收集器调用finalize 当对象即将从内存中释放时的方法 当异常发生时会发生什么finalize method GC 会继续进行并释放内存 还是 GC 将停止该对象的进程 如果异
  • 如何检测后面的代码中单击了哪个按钮?

    我有三个按钮 每个按钮都用于呼叫btn Clicked在他们的onClick事件 在后面的代码中 我想获取导致回发的按钮的 ID 我知道我可以分配每个按钮来调用不同的方法 但我想学习一些 ASP Net 还请告诉我哪种方法更有效 在不同的按
  • QTreeWidgetItem 中图标的位置

    My QTreeWidget有一个列 它的项目有一个复选框 一个图标和文本 如果用户在某个项目内单击 我想知道该图标是否被单击 如何找到图标的位置和大小QTreeWidgetItem 更新添加 这是我的最终解决方案的代码 根据 webcle
  • 如何将画布视图保存为 PNG 文件?

    我创建了画布 可用于在其上绘制一些形状 如何将其内容保存到用户 SD 卡上的 PNG 文件 查看此链接这个链接在此链接中您可以找到该方法 void saveImage try String filename Environment getE
  • C# 事件在幕后如何工作?

    我正在使用 C NET 3 5 我了解如何利用事件 如何在我的类中声明它们 如何从其他地方挂钩它们等等 一个人为的例子 public class MyList private List
  • 如何打开Android手电筒

    Update 看看我的回答 Original 我正在尝试在程序中打开 LG Revolution 上的相机手电筒 我使用的是手电筒模式方法 该方法适用于大多数手机 但不适用于 LG 手机 有谁知道如何让它在 LG 或特别是 Revoluti
  • Airflow 身份验证设置失败并显示“AttributeError:无法设置属性”

    Airflow 版本 1 8 密码身份验证设置 如中所述docs在该步骤失败 user password set the password 有错误 AttributeError can t set attribute 最好简单地使用Pass
  • React:推荐箭头还是普通函数?

    在我觉得手动函数 对象绑定和范围相关问题很令人头痛之后 我开始使用箭头函数 但最近我开始知道使用普通函数 ES5 比箭头函数 ES6 更好 我对这些功能的理解 React 中的正常功能 手动绑定对象 函数 以便在函数内使用状态或道具并避免与