与 TypeScript、React、Eslint 和简单的 Arrow Functions 组件作斗争

Ale*_*rto 50 typescript reactjs eslint eslint-config-airbnb eslintrc

我整个上午都在为这个问题苦苦挣扎,但在任何地方都找不到解决方案。我是打字稿的新手,我正在尝试使用 Eslint 和 Prettier 正确设置它,以确保代码格式正确。

所以,我在创建功能组件时面临的问题。根据备忘单,我正在尝试导出一个简单的组件,例如:

import React from "react";

type DivProps = {
  text: string;
};

const Div = ({ text }: DivProps): JSX.Element => (<div>{text}</div>)

export default Div;
Run Code Online (Sandbox Code Playgroud)

然而,eslint 抱怨说“函数组件不是函数表达式”。

运行修复时,它会将我的函数转换为未命名函数:

const Div = function ({ text }: DivProps): JSX.Element {
  return <div>{text}</div>;
};
Run Code Online (Sandbox Code Playgroud)

然后它会抱怨说“意外的未命名函数”。

即使我尝试将函数重构为:

function Div({ text }: DivProps): JSX.Element {
  return <div>{text}</div>;
};
Run Code Online (Sandbox Code Playgroud)

我仍然收到同样的错误,说“函数组件不是函数表达式”。

我的 .eslintrc.js 文件是:

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: ["airbnb", "plugin:@typescript-eslint/recommended", "prettier"],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: "module",
  },
  plugins: ["@typescript-eslint", "react-hooks", "prettier"],
  rules: {
    "react-hooks/rules-of-hooks": "error",
    "prettier/prettier": "error",
    "no-use-before-define": "off",
    "@typescript-eslint/no-use-before-define": ["error"],
    "react/jsx-filename-extension": [
      1,
      {
        extensions: [".tsx"],
      },
    ],
    "import/prefer-default-export": "off",
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        ts: "never",
        tsx: "never",
      },
    ],
  },
  settings: {
    "import/resolver": {
      typescript: {},
    },
  },
};
Run Code Online (Sandbox Code Playgroud)

感谢对此的任何帮助!

PS:如果您在 eslintrc 文件中看到任何需要修改/改进的内容,请告诉我。正如我所提到的,我是 TypeScript 的新手,所以我仍在尝试找出 linting 的最佳选项。

干杯!

亚历杭德罗

Ale*_*rto 60

好吧,所以我不知道这是否是正确的答案,但最终更改 Eslint 中的设置帮助我更改了组件的函数类型。我将以下规则添加到我的 .eslintrc.js 文件中:

"react/function-component-definition": [
  2,
  {
    namedComponents: "arrow-function",
    unnamedComponents: "arrow-function",
  },
],
Run Code Online (Sandbox Code Playgroud)

这样,eslint 将只接受组件的箭头函数,而不是函数表达式(默认)。

  • @LuanLuanLuan 找到了答案(如果你没有看这个问题)——这最终是 Airbnb linting 规则中的一个错误。下面我对这个问题的回答中有更多详细信息。 (3认同)

sli*_*fty 48

最终更新:eslint-config-airbnb自 版本 起已更正此问题19.0.4

最好的办法是将该软件包的副本更新到 19.0.4 或更高版本。


过去的更新:这实际上airbnb配置版本18.2.1至19.0.2中的一个错误

正确的设置应该是function-declaration,因此正确的解决方案是覆盖您的规则.eslintrc.js

"react/function-component-definition": [
  2,
  {
    namedComponents: "function-declaration",
  },
],
Run Code Online (Sandbox Code Playgroud)

^目前有一个开放的 PR,现在已合并 PR ,默认情况下会在爱彼迎设置中制作该补丁,因此此更改将使您的项目与预期设置保持一致。

注意:您可能需要考虑导航到相关问题并对其进行投票,以便维护人员知道您正在处理它。

现在这个问题已经解决,您应该将版本更新到 19.0.4 或更高版本。

另一种选择:降级爱彼迎规则

正如另一个答案所提到的:如果您愿意,您还可以将您的爱彼迎规则版本降级到引入“坏”规则之前(v18.2.1 是没有此规则的最新版本)。这是通过更新 package.json 来完成的:

"devDependencies": {
  ...
  "eslint-config-airbnb": "^18.2.1"
}
Run Code Online (Sandbox Code Playgroud)

请注意,这意味着您的项目不会使用最新的爱彼迎样式指南,因此您可能会决定最好简单地覆盖该规则。


我之前的答案,它将根据 linter 创建“有效”代码:

我也遇到过这个问题;我能够弄清楚如何编写符合爱彼迎规则的代码,但是......我发现结果非常尴尬,而且我不太确定为什么它会是首选结果。

在默认规则下,您需要(A)使用函数表达式定义组件,而且(B)您不能使用匿名函数(这是为了防止堆栈跟踪中的“匿名函数”),因此还必须将函数命名为:

const MyComponent = function MyComponent() { ... }
Run Code Online (Sandbox Code Playgroud)

所以用你的例子:

const Div = function Div({ text }: DivProps): JSX.Element {
  return <div>{text}</div>;
};
Run Code Online (Sandbox Code Playgroud)

这满足了 linter 但是...哎呀,我说得对吗?

  • 我有 eslint-config-airbnb 版本 19.0.4 和此错误 (5认同)

Bab*_*med 7

它解决了我的问题,所以你可以尝试这个

'react/function-component-definition': [
  2,
  {
    namedComponents: ['arrow-function', 'function-declaration'],
    unnamedComponents: 'arrow-function',
  },
],
Run Code Online (Sandbox Code Playgroud)