網站搜尋

reactjs - 在使用 TypeScript、React、Eslint 以及簡單的 Arrow 函式元件時遇到困難


我整個早上都在為這個問題而努力,卻在任何地方都找不到解決方案。我對 TypeScript 還很陌生,正在嘗試將它與 Eslint 和 Prettier 正確設置,以確保代碼格式正確。

所以,我在創建函數型組件時遇到的問題。根據備忘單,我正在嘗試導出一個簡單的組件,例如:

import React from "react";

type DivProps = {
  text: string;
};

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

export default Div;

然而,eslint 正在抱怨,說「函數組件不是函數表達式」。

當運行修復時,它會將我的函數轉換為一個無名函數:

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

然後它會抱怨說「意外的未命名函數」。

即使我試圖將函數重新構造為:

function Div({ text }: DivProps): JSX.Element {
  return <div>{text}</div>;
};

我仍然收到相同的錯誤,說「函數組件不是函數表達式」。

我的 .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: {},
    },
  },
};

感謝任何幫助!

附註:如果你看到 eslintrc 文件中有其他你想修改/改進的地方,請告訴我。如我所提,我是 TypeScript 新手,所以我仍在嘗試找出最適合的 linting 選項。

乾杯!

亞歷杭德羅

答案#1

好,所以我不知道這是否是正確的答案,但最終修改 Eslint 的設定幫助我改變了 Components 函數的類型。我在我的 .eslintrc.js 文件中添加了以下規則:

"react/function-component-definition": [
  2,
  {
    namedComponents: "arrow-function",
    unnamedComponents: "arrow-function",
  },
],

這樣一來,eslint 將只接受用箭頭函數定義的組件,而不是函數表達式(預設情況下)。

答案#2

最終更新: 這已在 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",
  },
],

^目前有一個已合併的 PR,旨在將該補丁設為 Airbnb 設定的預設值,所以這個更改將使你的專案與預期的設定保持一致。

注意:你可能會想考慮前往相關問題並點贊,讓維護者知道你正在處理它。

既然這個問題已經解決,你應該將你的版本更新到 19.0.4 或以上。

另一個選擇:降低Airbnb規則

如另一個答案所提到的:如果你願意,你也可以將你的 Airbnb 規則版本降級到引入「壞規則」之前的版本(v18.2.1 是沒有此規則的最新版本)。這可以通過更新你的 package.json 來完成:

"devDependencies": {
  ...
  "eslint-config-airbnb": "^18.2.1"
}

請注意,這意味著您的專案將不會使用最新的 Airbnb 風格指南,因此您可能會決定直接覆蓋該規則會更好。


我之前的回答,將會根據語法檢查器創建「有效」的程式碼:

我也遇到過這個問題;我能夠弄清楚如何寫出符合 Airbnb 規則的代碼,但是……我覺得結果相當尷尬,而且我不太確定為什麼這會是首選結果。

根據預設規則,你需要同時 (A) 使用函數表達式定義你的組件,但也 (B) 不能使用匿名函數(這是為了防止堆疊追蹤中出現「匿名函數」),因此還必須為函數命名:

const MyComponent = function MyComponent() { ... }

所以使用你的例子:

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

這符合程式碼檢查工具的要求,但是... 哎呀,我說得對吧?