为什么箭头语法优于纯React组件的标准函数?

时间:2018-03-15 17:51:59

标签: javascript reactjs ecmascript-6

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

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

export default foo;

而不是更传统的函数定义语法:

function foo() {
  return ...;
}

export default foo;

是否有理由更喜欢前者而不是后者?

4 个答案:

答案 0 :(得分:8)

我会说这是一个有点自以为是的选择。至少有几个原因导致 I (个人)将箭头功能用于纯功能组件作为非常糟糕的做法。以下是:

  1. 语法滥用。当我们定义函数组件时,我们不需要将其上下文预绑定到特定范围。无论如何,模块命名空间中的上下文(this)将是undefined。箭头功能的使用在这里由纯粹的美学原因决定,如简洁。但箭头作为语言特征的功能首先存在非常特定的目的,这不是酷感和简洁。

  2. 错误堆栈跟踪。箭头函数中抛出的异常将不那么具有描述性,因为箭头函数的定义是匿名的。这可能不是一个大问题,因为React项目最有可能配置正确的源映射支持,但如果使用了命名函数,堆栈跟踪仍然会更清楚。正如评论中所指出的,这不是真正的函数组件的问题,因为名称基本上是变量的名称。

  3. 日志记录不太方便。考虑这种非常典型的纯函数组件样式:

    const Header = ({ name, branding }) => (
      <header>
        ...
      </header>
    )
    
  4. 在上面的函数中,无法使用快速debugger语句或console.log。您必须暂时将其转换为类似的内容

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

    这对于更大的纯组件来说可能非常烦人。

    据说这是很多团队非常受欢迎的选择,默认情况下也是ESLint的首选,所以如果你没有看到它的问题,那么它可能没问题。

答案 1 :(得分:4)

实际上,它们之间没有任何区别。我在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命令,并得到如下所示的捆绑包:

(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选择了< em>箭头功能来定义功能组件。

答案 2 :(得分:1)

使用Arrow函数比使用常规函数更好,不仅因为synthax是干净的,而且您可以使用箭头函数编写更少的代码,还因为:

1-范围安全性:当一致地使用箭头函数时,一切都保证使用与根相同的thisObject。如果即使单个标准函数回调与一堆箭头函数混合在一起,那么范围也可能会变得混乱。

2-Compactness:箭头功能更易于读写。

3-Clarity:当几乎所有东西都是箭头功能时,任何常规功能都会立即用于定义范围。开发人员总是可以查找下一个更高的函数语句来查看thisObject是什么。

有关详细信息,您可以查看此问题

When should I use Arrow functions in ECMAScript 6?

答案 3 :(得分:0)

函数声明和箭头函数的本质不同,但是在您的问题范围内,它基本上是一种代码样式首选项。我个人更喜欢函数声明,因为我发现更容易发现该行代码的含义。

如果您将使用Arrow函数或Function声明,请尝试从上下文中更有意义的角度进行思考。为了使代码更整洁和易于阅读,这不仅关乎您编写的代码量,还关乎代码所表达的内容。

我倾向于使用箭头函数进行回调,例如[].map(() => {})