在HoC中使用React钩子时警告

时间:2019-05-24 08:13:27

标签: reactjs eslint react-hooks

我创建了一个更高阶的组件,该组件应该为我的组件添加一些其他功能。但是,当我在此组件中使用react钩子时,会收到以下eslint警告。

  

反应挂钩“ React.useEffect”不能在回调内调用。反应   挂钩必须在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

5 个答案:

答案 0 :(得分:3)

official React Hooks documentation说:

  

不要通过常规JavaScript函数调用Hook。相反,您可以:

     

✅从React函数组件中调用Hook。

     

✅从自定义挂钩中呼叫挂钩。

正如@AsafAviv所说,您应该将HOC重构为自定义钩子,以避免违反Rules of Hooks


原因是described in the FAQ

  

React如何将Hook调用与组件相关联?

     

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

     

每个组件都有一个内部的“内存单元”列表。它们只是JavaScript对象,我们可以在其中放置一些数据。当您调用类似于useState()的Hook时,它将读取当前单元格(或在第一个渲染期间将其初始化),然后将指针移至下一个单元格。这就是多个useState()调用的方式分别获得独立的本地状态的方式。

答案 1 :(得分:2)

转换

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

将您的HOC置于函数内部(当在HOC返回的箭头函数中使用时,反应钩/规则钩将显示您显示的警告)

因此,将其更改为

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

效果就会被触发。

Here is a working example on codesandbox

答案 2 :(得分:0)

您可以在功能组件或自定义挂钩中使用react挂钩。 重写您的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)

答案 3 :(得分:0)

Short Answer:您只需要将回调更改为 PascalCase 函数或 useSomething 函数。这是因为 eslint 规则有一些启发式方法,您需要遵循这些规则才能检测组件。

您需要将代码更改为

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

答案 4 :(得分:-1)

这是我避免错误的建议

对我有用

`

import * as React from "react";

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

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

  return <Component {...props} />;
};

export default Wrapper(Hello);

`