【问题标题】:Can I use useState inside HOC (High order component)?我可以在 HOC(高阶组件)中使用 useState 吗?
【发布时间】:2021-06-07 03:22:03
【问题描述】:

我有一个返回功能组件的 HOC(高阶组件)。 我想使用 useState 但收到以下错误消息:

“src/HOC.js 第 5:35 行:不能在回调中调用 React Hook “useState”。 React Hooks 必须在 React 函数组件或自定义 React Hook 函数 react-hooks/rules-of-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,而不是使用自定义挂钩?因为 Hooks 取代了 HOC。如果您想要一个像 HOC 一样的自定义挂钩(可以“挂钩”在其他组件上),我可以发布答案。
  • 语法不正确。你在 setCount 之后关闭块吗?
  • @RahulSharma 这是一个错字。刚刚修好了。
  • @IamL 如果它能让我达到同样的效果,看看它是如何工作的将会非常有趣。
  • @JohnBonjon 我发布了答案

标签: reactjs react-hooks use-state high-order-component


【解决方案1】:

正如 cmets 中所讨论的,我将发布上面 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, handleClick, 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 完全相同。

【讨论】:

  • 它有效,但它可能有一个缺点。如果我想将一个值(来自输入)传递给钩子,那么它不会总是加一个,而是添加传递的值呢?
  • @JohnBonjon 这很简单,我已经针对特定场景更新了答案。您所要做的就是添加一个参数。
  • 我不是这个意思。我是说用户(来自输入)是否可以传递要添加的值。 (即 47)。我不能有 47 个按钮。它必须是一个输入。 HOC 让你做到这一点。
  • @JohnBonjon 这很简单,只需在钩子中添加另一个函数并在您的输入中调用它。我编辑了我的答案。
猜你喜欢
  • 2022-01-19
  • 2020-02-06
  • 2019-01-07
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多