当前位置: 首页 > 知识库问答 >
问题:

在HoC中使用react钩子时发出警告

叶冥夜
2023-03-14

我已经创建了一个高阶组件,它应该为我的组件添加一些额外的功能。然而,当我在这个组件中使用反应钩子时,我会得到以下eslint警告。

不能在回调内调用React钩子“React.useffect”。必须在React函数组件或自定义React钩子函数中调用React钩子。(吊钩/吊钩规则)

为什么我会收到这个警告?在HoC中使用钩子被认为是不好的做法吗?

最简单的例子:

const Hello = props => <p>Greetings {props.name}</p>;

const Wrapper = Component => props => {
  React.useEffect(() => {
    // Do something here
  }, []);
  return <Component {...props} />;
};

export default Wrapper(Hello)

Codesandbox:https://codesandbox.io/s/proud-tree-5kscc

共有3个答案

梁丘兴腾
2023-03-14

您可以在功能组件或自定义钩子中使用反应钩子。重写您的HOC:

const Hello = props => <p>Greetings {props.name}</p>;

const HookDoSomething = () => {
  React.useEffect(() => {
    // Do something here
  }, []);
}

const Wrapper = Component => props => {
  HookDoSomething()
  return <Component {...props} />;
};

export default Wrapper(Hello)
麻茂材
2023-03-14

官方文件说:

不要从常规JavaScript函数调用钩子。相反,您可以:

✅ 来自React函数组件的调用挂钩。

✅ 从自定义钩子调用钩子。

正如@asafavi所说,您应该将HOC重构为一个定制的钩子,以避免违反钩子的规则。

原因在常见问题解答中描述如下:

React跟踪当前渲染组件。多亏了钩子的规则,我们知道钩子只能从React组件调用(或者自定义钩子,也只能从React组件调用)。

有一个与每个组件相关的“存储单元”的内部列表。它们只是我们可以放一些数据的JavaScript对象。当你调用像useState()这样的钩子时,它会读取当前单元格(或者在第一次渲染时初始化它),然后将指针移动到下一个单元格。这就是多个useState()调用各自获得独立本地状态的方式。

翟黎明
2023-03-14

转换

props => {
  React.useEffect(() => {
    // Do something here
  }, []);
  return <Component {...props} />;
};

在您的HOC内部,指向一个函数(react hooks/rules of hooks抛出您在HOC返回的arrow函数中使用时显示的警告)

所以,把它改成

const Wrapper = Component =>
  function Comp(props) {
    React.useEffect(() => {
      console.log("useEffect");
    }, []);
    return <Component {...props} />;
  };

效果就会被触发。

下面是一个关于codesandbox的工作示例

 类似资料:
  • 我目前正在更新我的应用程序,使之适应React 16.8,这样我就可以使用令人敬畏的新钩子功能。更新React包(以及所有依赖项)不是问题,一切正常。但当我尝试设置ESLint时,当我尝试使用钩子时,它总是给我以下错误: React钩子“useffect”在函数“projectInfo”中调用,该函数既不是React函数组件,也不是自定义React钩子函数 我的组件看起来像这样: 我的文件如下:

  • 在React的官方文件中提到- 如果您熟悉React类生命周期方法,那么可以将useEffect钩子看作componentDidMount、componentDidUpdate和componentWillUnmount的组合。 我的问题是--我们如何在钩子中使用生命周期方法?

  • 我正努力让你去工作。以下是功能组件: 我称之为: 我得到一个错误,如下所示: 错误:无效的钩子调用。钩子只能在函数组件的主体内部调用。发生这种情况的原因如下:1。React和渲染器(如React DOM)2的版本可能不匹配。你可能违反了Hooks 3的规则。同一应用程序中可能有多个React副本。 我已经调试并确认我使用的是单一版本。也许我使用状态钩子不正确? 这里是我调用自定义钩子的地方:

  • 我试图在react with typescript中创建一个登录表单。但setEmail方法不接受该值。它表示“string”类型的参数不能分配给“SetStateAction”类型的参数。我该怎么解决它?

  • 我第一次面对的问题很小。我试图使用一个简单的useState,但出于某种原因,我不明白为什么React会给我一个错误,不管我想做什么--没有什么能修复它。 这是错误的图像:错误描述: 错误:无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一:1.React和呈现器(例如React DOM)2的版本可能不匹配。你可能违反了钩子3的规则。在同一个应用程序中可能有多个React副

  • 我发现有几种方法可以用钩子处理用户的文本输入。用钩子处理输入的更好或更合适的方法是什么?你会用哪一种? 1)处理输入的最简单的钩子,但是你有更多的字段,你必须写更多重复的代码。 活动: 2) 与上面的示例类似,但具有动态键名 活动: 3) 作为的替代方案,正如ReactJS文档中所述,通常比更可取。 活动: 4) 将返回一个回调的备忘录版本,该版本仅在其中一个依赖项发生更改时才会更改。 活动: