创建钩子时真的需要导入'React'吗? (反应钩子)

Posted

技术标签:

【中文标题】创建钩子时真的需要导入\'React\'吗? (反应钩子)【英文标题】:Do you really need to import 'React' when creating hooks? (React-hooks)创建钩子时真的需要导入'React'吗? (反应钩子) 【发布时间】:2019-11-07 09:42:43 【问题描述】:

我看到了https://reactjs.org/docs/hooks-custom.html 他们总是这样做的例子:

import React,  useState, useEffect  from 'react';

但是React 并没有真正用在文件中,我们真的需要它吗?为什么?

我问这个问题是因为我遇到了 eslint 的问题:

'React' is defined but never used no-unused-vars - 我正在使用 create-react-app 3.0.1,其中 eslint 已包含在内 - (我不确定如何解决此问题 - 已经尝试过 this 并尝试将其添加到包中.json eslintConfig 但仍然没有)

【问题讨论】:

“但 React 并没有真正在文件中使用”如果你的代码中有 jsx,它实际上是被使用的。如果不是,您只能导入钩子,例如,如果您的代码包含自定义钩子定义并且本身不涉及元素创建。 【参考方案1】:

如果要渲染JSX,则需要React

为避免出现eslint 警告,您应该使用eslint-plugin-react 中的react-in-jsx-scope 规则。

在该规则中,它还解释了为什么在文件中需要React,即使你不使用它(你认为你不使用它,但如果你渲染JSX,你会这样做)。

使用 JSX 时,<a /> 扩展为 React.createElement("a")。因此 React 变量必须在范围内。 如果您使用@jsx pragma,则此规则将检查指定变量而不是 React 变量。

【讨论】:

hmmm 我对我的组件使用相同的规则,它没有抱怨,它只抱怨钩子文件。 (无论如何都接受了答案,因为它解释了为什么我需要导入 React,这是这​​个问题的标题) 在钩子文件上,你输入React,然后它会给出警告,在其他组件中,你可能在class Foo extends React.Component中使用React @IamL 期望什么? 它会在钩子文件上抛出警告(回到上面的问题)? @IamL 是的。你有 2 条规则。一个说,no-unused-vars,这会运行你的代码并检查代码中是否使用了变量。 react-in-jsx-scope 将寻找React 并检查您是否使用JSX,如果是,它将覆盖no-unused-varsReact 变量,因为它知道稍后,JSX 将使用变量React 和它转译。 no-unused-vars 不知道你会转译你的代码并在以后使用React【参考方案2】:

React 17 有一个新的 JSX 转换,它不再需要导入(也向后移植到新版本 16.14.0、15.7.0 和 0.14.10)。你可以在这里读更多关于它的内容: https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html

// no import needed
const App = () => <div>hello!</div>

但是,您仍然需要导入才能使用钩子:

import  useState  from 'react'

const App = () => 
  const [stuff, setStuff] = useState('stuff')

  return <div>stuff</div>

文档还链接到脚本以自动更新项目中的所有文件以修复所有导入。就我个人而言,我习惯于只使用React.useWhatever 表单,因此我不需要弄乱导入语句,但使用命名导入可能会减少最终包的大小。

文档说命名导入现在是推荐的方式,所以不推荐这样做,但如果你真的想保留 React 导入,你可以设置下面的 eslint 规则来阻止它抱怨。请注意,这将继续在所有文件中使用它。

"react/jsx-uses-react": "error"

【讨论】:

【参考方案3】:

来自 React 官方文档:

从根本上说,JSX 只是为 React.createElement(component, props, ...children) 函数。 JSX 代码:

&lt;MyButton color="blue" shadowSize=2&gt;Click Me&lt;/MyButton&gt;

编译 进入:

React.createElement(MyButton, color: 'blue', shadowSize: 2,'Click Me' )

你也可以使用标签的自闭合形式,如果 没有孩子。所以:

<div className="sidebar" /> 

编译成:

React.createElement('div', className: 'sidebar', null )

https://reactjs.org/docs/jsx-in-depth.html

EDIT Hooks 也在 React 命名空间下,React.useState ...等

【讨论】:

您的回答适用于文件中有JSX的情况,但是在OP引用的自定义钩子示例中,文件中没有JSX。

以上是关于创建钩子时真的需要导入'React'吗? (反应钩子)的主要内容,如果未能解决你的问题,请参考以下文章

在 HoC 中使用反应钩子时的警告

如何使用新的反应路由器钩子测试组件?

OnSubmit 函数不会更新 React 中的反应钩子状态变量

反应表单钩子如何验证选择选项

反应库中的反应钩子给出无效的钩子调用错误

为什么叫 React Hooks