Function component is not a function declaration. eslint(react/function-component-definition)报错原因

文章介绍了eslint-plugin-react中的function-component-definition规则,该规则强制要求函数组件使用特定的函数类型,支持命名组件的函数声明、箭头函数和函数表达式,并详细解释了规则选项和如何设置组件的函数类型偏好。同时提到了JavaScript和TypeScript中的自动修复限制。


这个是eslint-plugin-react 的规则!

阅读该 linting 规则的文档:https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/function-component-definition.md

它告诉你,这个规则它期望将组件声明为函数声明。

为函数组件强制实施特定函数类型 ( react/function-component-definition )

此规则旨在为函数组件强制实施一致的函数类型。默认情况下,它更喜欢命名组件的函数声明和未命名组件的函数表达式。

Examples of incorrect code for this rule:
此规则的错误代码示例:

// function expression for named component
const Component = function (props) {
  return <div>{props.content}</div>;
};

// arrow function for named component
const Component = (props) => {
  return <div>{props.content}</div>;
};

// arrow function for unnamed component
function getComponent() {
  return (props) => {
    return <div>{props.content}</div>;
  };
}

Rule Options 规则选项


此规则将选项对象作为第二个参数,其中可以指定组件的首选函数类型。选项对象的第一个属性可以是 "namedComponents" 、 "function-declaration" "arrow-function" 、 "function-expression" 或包含其中任何一个的数组,并且作为 'function-declaration' 其默认值。第二个属性可以是 "unnamedComponents" "function-expression" 、 "arrow-function" 或包含其中任何一个的数组,并且具有 'function-expression' 默认值。

"react/function-component-definition": [<enabled>, {
  "namedComponents": "function-declaration" | "function-expression" | "arrow-function" | Array<"function-declaration" | "function-expression" | "arrow-function">,
  "unnamedComponents": "function-expression" | "arrow-function" | Array<"function-expression" | "arrow-function">
}]
此规则的错误代码示例:
// only function declarations for named components
// [2, { "namedComponents": "function-declaration" }]
const Component = function (props) {
  return <div />;
};

const Component = (props) => {
  return <div />;
};

// only function expressions for named components
// [2, { "namedComponents": "function-expression" }]
function Component (props) {
  return <div />;
};

const Component = (props) => {
  return <div />;
};

// only arrow functions for named components
// [2, { "namedComponents": "arrow-function" }]
function Component (props) {
  return <div />;
};

const Component = function (props) {
  return <div />;
};

// only function expressions for unnamed components
// [2, { "unnamedComponents": "function-expression" }]
function getComponent () {
  return (props) => {
    return <div />;
  };
}

// only arrow functions for unnamed components
// [2, { "unnamedComponents": "arrow-function" }]
function getComponent () {
  return function (props) {
    return <div />;
  };
}

此规则的正确代码示例:
// only function declarations for named components
// [2, { "namedComponents": "function-declaration" }]
function Component (props) {
  return <div />;
}

// only function expressions for named components
// [2, { "namedComponents": "function-expression" }]
const Component = function (props) {
  return <div />;
};

// only arrow functions for named components
// [2, { "namedComponents": "arrow-function" }]
const Component = (props) => {
  return <div />;
};

// only function expressions for unnamed components
// [2, { "unnamedComponents": "function-expression" }]
function getComponent () {
  return function (props) {
    return <div />;
  };
}

// only arrow functions for unnamed components
// [2, { "unnamedComponents": "arrow-function" }]
function getComponent () {
  return (props) => {
    return <div />;
  };
}

Unfixable patterns 无法修复的模式

There is one unfixable pattern in JavaScript.
JavaScript 中有一个无法修复的模式。

It has to do with the fact that this is valid syntax:
这与这是有效语法的事实有关:

export default function getComponent () {
  return <div />;
}

While these are not:

export default var getComponent = () => {
  return <div />;
}

export default var getComponent = function () {
  return <div />;
}

These patterns have to be manually fixed.
这些模式必须手动修复。

Heads up, TypeScript users

请注意,自动修复器对于 TypeScript 用户来说有些限制。

以下模式不能在 TypeScript 中自动修复:

// function expressions and arrow functions that have type annotations cannot be autofixed to function declarations
// [2, { "namedComponents": "function-declaration" }]
const Component: React.FC<Props> = function (props) {
  return <div />;
};

const Component: React.FC<Props> = (props) => {
  return <div />;
};

// function components with one unconstrained type parameter cannot be autofixed to arrow functions because the syntax conflicts with jsx
// [2, { "namedComponents": "arrow-function" }]
function Component<T>(props: Props<T>) {
  return <div />;
};

const Component = function <T>(props: Props<T>) {
  return <div />;
};

// [2, { "unnamedComponents": "arrow-function" }]
function getComponent() {
  return function <T>(props: Props<T>) => {
    return <div />;
  }
}

如果存在多个类型参数,或者只有一个受约束的类型参数,则类型参数不会产生语法冲突。

可以在 TypeScript 中自动修复以下模式:

// autofix to function expression with type annotation
// [2, { "namedComponents": "function-expression" }]
const Component: React.FC<Props> = (props) => {
  return <div />;
};

// autofix to arrow function with type annotation
// [2, { "namedComponents": "function-expression" }]
const Component: React.FC<Props> = function (props) {
  return <div />;
};

// autofix to named arrow function with one constrained type parameter
// [2, { "namedComponents": "arrow-function" }]
function Component<T extends {}>(props: Props<T>) {
  return <div />;
}

const Component = function <T extends {}>(props: Props<T>) {
  return <div />;
};

// autofix to named arrow function with multiple type parameters
// [2, { "namedComponents": "arrow-function" }]
function Component<T1, T2>(props: Props<T1, T2>) {
  return <div />;
}

const Component = function <T1, T2>(props: Props<T2>) {
  return <div />;
};

// autofix to unnamed arrow function with one constrained type parameter
// [2, { "unnamedComponents": "arrow-function" }]
function getComponent() {
  return function <T extends {}> (props: Props<T>) => {
    return <div />;
  };
}

// autofix to unnamed arrow function with multiple type parameters
// [2, { "unnamedComponents": "arrow-function" }]
function getComponent() {
  return function <T1, T2>(props: Props<T1, T2>) => {
    return <div />;
  }
}

When Not To Use It
何时不使用它

如果您对一致类型的函数组件不感兴趣。

src/audio_io.c: In function 'audio_init': src/audio_io.c:37:5: warning: implicit declaration of function 'ESP_LOGE'; did you mean 'ESP_OK'? [-Wimplicit-function-declaration] ESP_LOGE("TEST", "1111\n"); ^~~~~~~~ ESP_OK Linking .pio\build\esp32s3box\firmware.elf c:/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: .pio\build\esp32s3box\src\audio_io.c.o:(.literal.audio_init+0x18): undefined reference to `ESP_LOGE' c:/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: .pio\build\esp32s3box\src\audio_io.c.o: in function `audio_init': D:\project_study\esp32\esp_pio_test/src/audio_io.c:37: undefined reference to `ESP_LOGE' c:/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: D:\project_study\esp32\esp_pio_test/src/audio_io.c:39: undefined reference to `ESP_LOGE' c:/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: D:\project_study\esp32\esp_pio_test/src/audio_io.c:59: undefined reference to `ESP_LOGE' c:/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: D:\project_study\esp32\esp_pio_test/src/audio_io.c:62: undefined reference to `ESP_LOGE' c:/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: .pio\build\esp32s3box\src\audio_io.c.o:D:\project_study\esp32\esp_pio_test/src/audio_io.c:83: more undefined references to `ESP_LOGE' follow collect2.exe: error: ld returned 1 exit status *** [.pio\build\esp32s3box\firmware.elf] Error 1
06-18
<think>我们正在解决ESP32开发中遇到的"ESP_LOGEundefinedreference"链接错误。根据引用[2]中的信息,ESP_LOG_ERROR是日志级别枚举的一部分,而ESP_LOGE是用于输出错误日志的宏。出现未定义引用错误通常是因为在链接阶段找不到该符号的定义。可能的原因和解决方案如下:1.未包含必要的头文件:确保在源文件中包含了`esp_log.h`头文件,因为该宏定义在此头文件中。```c#include"esp_log.h"```2.未链接日志库:在编译时需要链接ESP-IDF的日志库(`log`库)。在CMakeLists.txt(或Makefile)中,确保添加了`log`组件作为依赖。例如,在CMakeLists.txt中:```cmakeset(COMPONENTSlog...)#确保log在组件列表中```或者使用`target_link_libraries`(如果使用idf_component_register):```cmakeidf_component_register(SRCS"main.c"INCLUDE_DIRS"."REQUIRESlog)```3.日志组件未正确初始化:虽然这通常不会导致链接错误,但确保在程序开始调用了`esp_log_level_set`来设置日志级别(可选,但建议)。4.检查拼写错误:确保正确拼写了`ESP_LOGE`(注意大写和下划线)。如果以上步骤都正确,但问题仍然存在,请检查你的ESP-IDF版本,并确保日志组件没有被意外排除在构建之外。参考引用[2]中关于日志级别的定义,我们确认`ESP_LOGE`是存在的,因此问题很可能在于编译配置。现在,让我们生成相关问题。</think>### ESP32 ESP_LOGE 未定义引用链接错误解决方案 当在ESP32开发中出现`ESP_LOGE undefined reference`链接错误时,通常是由于日志系统配置问题导致的。以下是系统化的解决步骤: 1. **检查头文件包含** 确保所有使用日志功能的源文件顶部包含ESP日志头文件: ```c #include "esp_log.h" ``` 2. **验证组件依赖** 在`CMakeLists.txt`中必须声明对`log`组件的依赖(ESP-IDF 4.1+): ```cmake idf_component_register( SRCS "main.c" INCLUDE_DIRS "." REQUIRES log # 关键依赖 ) ``` 3. **检查日志级别配置** 确认`menuconfig`中的日志级别设置: ```bash idf.py menuconfig ``` 路径: `Component config` → `Log output` → `Default log verbosity` 确保至少设置为`Error`级别(参考日志级别定义[^2])。 4. **验证宏拼写** 检查代码中宏名称的正确性: ```c ESP_LOGE(TAG, "Error message"); // 正确 // 常见错误:ESP_LOG_E / ESP_ERROR 等无效形式 ``` 5. **清理并重建项目** 执行深度清理后重新编译: ```bash idf.py fullclean idf.py build ``` **根本原因分析**: 此错误表明链接器找不到`ESP_LOGE`的实现,通常因为: - 缺少`log`组件链接(解决方案2) - 日志系统被编译器优化掉(解决方案3) - 头文件未正确包含(解决方案1) 当正确配置后,日志系统将按预设级别工作(如`ESP_LOG_ERROR`对应错误输出[^2])。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yusirxiaer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值