我可以在 HOC高阶组件中使用 useState 吗?

问题描述

我有一个返回函数组件的 HOC(高阶组件)。 我想使用 useState 但我收到此错误消息:

“src/HOC.js 第 5:35 行:无法在回调中调用 React Hook “useState”。必须在 React 函数组件或自定义 React Hook 函数 react-hooks/rules-of-hooks 中调用 React Hooks”

import React,{ useState } from "react";

const HOC = (Component,data) => {
    return () => {
        const [count,setCount] = useState(data); // Error here
        const handleClick = () => {
            setCount(count + 1);
        };
        return (
            <Component
                countNumber={count}
                handleClick={handleClick}
            />
        )
    }
};

export default HOC;
import React from "react";
import HOC from "./HOC";

const LikesCount = ({countNumber,handleClick}) => {
    return (
        <div>
            {countNumber} <br />
            <button onClick={handleClick}>Like</button>
        </div>
    );
}

const EnhancedLikes = HOC(LikesCount,5);

export default EnhancedLikes;

有没有办法在这种 HOC 场景中使用 useState?

解决方法

正如评论中所讨论的,我将发布上面 HOC 的自定义钩子副本:

就我在您的代码中的理解,您需要一个 HOC,您可以将它“挂钩”到组件上,然后它会执行计数。

因此,您可以创建自定义挂钩:

const useCounter = (default = 0) => {
      const [count,setCount] = useState(default);
      const [add,setAdd] = useState(0);
      const handleClick = (base = 0) => {
          setCount(count + base + add);
      };
      const onSetAdd = (e) => setAdd(e.target.value);
      
      return {count,handleClick,onSetAdd};
}

现在将其挂钩到功能组件中:


const LikesCount = () => {
    const {count,onSetAdd} = useCounter(0);
    const onAddOne = () => handleClick(); // default is 1,so passing none = one
    const onAddTwo = () => handleClick(2);
    const onAddThree = () => handleClick(3);
   

    return (
        <div>
            <input type="number" onChange={onSetAdd} value={add} />
            {count} <br />
            <button onClick={onAddOne}>Like</button>
            <button onClick={onAddTwo}>Add 2</button>
            <button onClick={onAddThree}>Add 3</button>
        </div>
    );
}

export default LikesCount;

就是这样,然后您可以在任何想要计数器的组件上添加 ff 代码:

const {count,handleClick} = useCounter(0);

以上代码的作用与您提供的示例 HOC 完全相同。