【问题标题】:React hook error when changing size of rendered array更改渲染数组的大小时反应钩子错误
【发布时间】:2021-09-20 08:34:10
【问题描述】:

我收到以下错误:React Error: "Rendered more hooks than during the previous render",这是因为在我渲染的映射数组中,按钮有自己的 useState 挂钩。

所以我有一个从列表中呈现的项目数组。最初只显示 3 个项目,单击按钮将加载整个列表。

问题是项目内部可以是多个 ProjectButtons,而这些 ProjectButtons 是组件,因为我想使用 useState 挂钩来使用特殊的悬停状态。

但是当我更改正在渲染的项目列表的大小时,由于 ProjectButton 组件中的 useState 挂钩,它会引发错误。

import { projects } from "../lib/projectList";

const Projects: FC = () => {
    // Initially use a portion of the array
    const [projectArray, setProjectArray] = useState(projects.slice(0, 3));

    // Load the whole array on button click
    const loadMoreProjects = () => {
        setProjectArray([...projects]);
    }

    const ProjectButton = (button: { type: string, link: string }) => {
        // Removing this useState hook fixes the problem, but I need it for my design
        const [hoverColor, setHoverColor] = useState("#0327d8");

        const handleMouseEnter = () => {
            setHoverColor("white");
        }
        const handleMouseLeave = () => {
            setHoverColor(original);
        }

        return (
            <a href={button.link} rel="noreferrer" target="_blank" key={button.link}>
                <button onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
                    <WebsiteIcon className="projectButtonIcon" fill={hoverColor} />
                    <p>{button.type}</p>
                </button>
            </a>
        );
    }

    return projectArray.map(project => (
        ...
        <div className="projectLinks">
            {project.buttons.map(button => ProjectButton(button))}
        </div>
        ...
        <Button onClick={loadMoreProjects}>Load More</Button>
    ));
}

【问题讨论】:

    标签: reactjs typescript react-hooks react-typescript


    【解决方案1】:

    您已经在 Projects 组件中定义了 ProjectButton,因此您打破了挂钩规则 - 特别是“Only Call Hooks at the Top Level”。

    ProjectButton 组件移出Projects 的范围,它会很高兴。

    【讨论】:

      【解决方案2】:

      发生这种情况是因为您在函数内部使用了钩子,并且应该直接在组件内部使用它。 如果您将 ProjectButton 创建为组件而不是函数,则可以解决此问题。

      这是更新后的代码:

      import { projects } from "../lib/projectList";
      
      
      
      const ProjectButton = (button) => {
        // Removing this useState hook fixes the problem, but I need it for my design
        const [hoverColor, setHoverColor] = useState("#0327d8");
      
        const handleMouseEnter = () => {
          setHoverColor("white");
        };
        const handleMouseLeave = () => {
          setHoverColor(original);
        };
      
        return (
          <a href={button.link} rel="noreferrer" target="_blank" key={button.link}>
            <button onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
              <WebsiteIcon className="projectButtonIcon" fill={hoverColor} />
              <p>{button.type}</p>
            </button>
          </a>
        );
      };
      
      const Projects: FC = () => {
          // Initially use a portion of the array
          const [projectArray, setProjectArray] = useState(projects.slice(0, 3));
      
          // Load the whole array on button click
          const loadMoreProjects = () => {
              setProjectArray([...projects]);
          }
      
          return projectArray.map(project => (
              ...
              <div className="projectLinks">
                  {project.buttons.map((button) => (
                    <ProjectButton {...button} />
                   ))}
              </div>
              ...
              <Button onClick={loadMoreProjects}>Load More</Button>
          ));
      }
      

      【讨论】:

        猜你喜欢
        • 2021-12-01
        • 1970-01-01
        • 2021-10-12
        • 2021-02-09
        • 1970-01-01
        • 2019-10-02
        • 2020-08-03
        • 2020-05-26
        • 2021-08-23
        相关资源
        最近更新 更多