javascript 为什么对于函数式React组件,箭头语法比函数声明更受欢迎?

alen0pnh  于 2023-08-02  发布在  Java
关注(0)|答案(5)|浏览(135)

我总是看到用箭头函数语法定义的函数式React组件的例子:

const foo = () => (...);

export default foo;

字符串
而不是更传统的函数声明语法:

export default function foo() {
  return ...;
}


有理由选择前者而不是后者吗?

nom7f22z

nom7f22z1#

我认为这是一个有点固执己见的选择。至少有几个原因可以解释为什么 * 我 *(个人)认为将箭头函数用于纯函数式组件是非常糟糕的做法。以下是这些:
1.语法滥用。当我们定义函数组件时,我们不需要预先将其上下文绑定到特定的作用域。在模块命名空间中,上下文(this)将始终是undefined。箭头功能的使用在这里是由纯粹的美学原因如简洁性决定的。但箭头功能作为语言特征,首先有一个非常特定的存在目的,这不是“酷”和简洁。
1.错误堆栈跟踪。在箭头函数中抛出的异常描述性较弱,因为箭头函数根据定义是匿名的。这可能不是一个大问题,因为React项目很可能会配置适当的源Map支持,但如果使用命名函数,堆栈跟踪仍然会更清晰一些。正如注解中所指出的,这实际上不是函数组件的问题,因为名称基本上就是变量的名称。
1.不太方便的日志记录。考虑这个非常典型的纯函数组件风格:

const Header = ({ name, branding }) => (
  <header>
    ...
  </header>
)

字符串
在上面的函数中,不可能抛出快速的debugger语句或console.log。您将不得不暂时将其转换为这样的内容

const Header = function ({ name, branding }) { 
  console.log(name)
  return (
    <header>
      ...
    </header>
  )
}


这可能非常烦人,尤其是对于更大的纯功能组件。
也就是说,这对许多团队来说是一个非常受欢迎的选择,也是ESLint默认的首选,所以如果你没有看到它的问题,那么它可能是好的。

u5rb5r59

u5rb5r592#

实际上,它们之间没有区别,我在CodeSandBox上做了一个little project,做了两个简单的组件,其中一个是Arrow组件,使用箭头函数:

import React from 'react';

const MyArrowComponent = () => (
  <main>
    <h2>Arrow</h2>
  </main>
);

export default MyArrowComponent;

字符串
另一个是使用函数声明的Declaration组件:

import React from "react";

function MyFunctionComponent() {
    return (
        <main>
            <h2>Declaration</h2>
        </main>
    );
}

export default MyFunctionComponent;


然后我运行yarn build命令,得到如下所示的bundle:

(window.webpackJsonp = window.webpackJsonp || []).push([[0], {
  14: function (e, n, t) {
    "use strict";
    t.r(n);
    var a = t(0), r = t.n(a), l = t(2),
        c = t.n(l), u = t(3), i = t(4), o = t(6), m = t(5), E = t(7);
    var p = function () {
      return r.a.createElement("main", null, r.a.createElement("h2", null, "Declaration"))
    }, s = function () {
      return r.a.createElement("main", null, r.a.createElement("h2", null, "Arrow"))
    }, d = function (e) {
      function n() {
            return (
              Object(u.a)(this, n),
              Object(o.a)(this, Object(m.a)(n).apply(this, arguments))
      }
      return Object(E.a)(n, e), Object(i.a)(n, [{
        key: "render", value: function () {
          return r.a.createElement(
            'div',
            null,
            r.a.createElement('div', null, 'Hi'),
            r.a.createElement(p, null),
            r.a.createElement(s, null)
          );
        }
      }]), n
    }(r.a.Component);
    c.a.render(r.a.createElement(d, null), document.getElementById("root"))
  }, 8: function (e, n, t) {
    e.exports = t(14)
  }
}, [[8, 1, 2]]]);


请注意ArrowDeclaration组件的定义:

var p = function () {
  return r.a.createElement("main", null, r.a.createElement("h2", null, "Declaration"))
}, s = function () {
  return r.a.createElement("main", null, r.a.createElement("h2", null, "Arrow"))
}


它们的定义方式是一样的,所以它们之间肯定没有区别,这完全是基于开发人员对代码可读性和干净代码的态度,基于我们团队的ESLint 5.x,我们选择了 * 箭头函数 * 来定义功能组件。

4bbkushb

4bbkushb3#

函数声明和箭头函数在本质上是不同的,但在你的问题范围内,它基本上是一种代码风格偏好。我个人更喜欢函数声明,因为我发现它更容易发现那行代码的含义。
如果你将使用箭头函数或函数声明,试着考虑在上下文中什么更有意义。为了使代码简洁易读,不仅要考虑编写的代码数量,还要考虑代码所表达的内容。
我倾向于使用箭头函数进行回调,例如[].map(() => {})

enxuqcxy

enxuqcxy4#

其他答案中没有提到的几点:

  • 对于箭头函数组件,当在Chrome/Firefox中使用React开发工具时,这些组件会显示为Anonymous,这使得调试更加困难。这些Anonymous组件也遍布开发工具,包括性能火焰树。功能组件在开发工具中显示其名称。
  • 标准函数声明可以在一行中定义。您不需要在文件中稍后定义export default。这也使得添加/删除default关键字变得更容易。
export default async function MyComponent() {
  ...
}

字符串

au9on6nz

au9on6nz5#

使用Arrow函数比使用常规函数要好得多,不仅因为语法干净,你可以用Arrow函数写更少的代码,还因为:
1.范围安全性:当一致使用箭头函数时,所有内容都保证使用相同的thisObject作为根。即使是一个标准函数回调与一堆箭头函数混合在一起,作用域也有可能变得混乱。
1.压实度:箭头函数更易于读取和写入。
1.清晰度:当几乎所有东西都是箭头函数时,任何常规函数都会立即突出来定义范围。开发人员总是可以查找下一个更高的函数语句来查看这个对象是什么。
更多细节,可以看看这些问题
When should I use Arrow functions in ECMAScript 6?

相关问题