更改渲染数组大小时反应挂钩错误
React hook error when changing size of rendered array
我收到以下错误:React Error: "Rendered more hooks than during the previous render"
,这是因为在我呈现的映射数组中是具有自己的 useState 挂钩的按钮。
所以我有一组从列表中呈现的项目。最初只显示 3 个项目,单击一个按钮将加载整个列表。
问题是项目内部可以有多个 ProjectButton,而这些 ProjectButton 是组件,因为我想使用 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>
));
}
您在 Projects
组件中定义了 ProjectButton
,因此您违反了钩子规则 - 特别是“Only Call Hooks at the Top Level”。
将 ProjectButton
组件移出 Projects
的范围,它会很高兴。
发生这种情况是因为您在函数内部使用了钩子,它应该直接在组件内部使用。
如果您将 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>
));
}
我收到以下错误:React Error: "Rendered more hooks than during the previous render"
,这是因为在我呈现的映射数组中是具有自己的 useState 挂钩的按钮。
所以我有一组从列表中呈现的项目。最初只显示 3 个项目,单击一个按钮将加载整个列表。
问题是项目内部可以有多个 ProjectButton,而这些 ProjectButton 是组件,因为我想使用 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>
));
}
您在 Projects
组件中定义了 ProjectButton
,因此您违反了钩子规则 - 特别是“Only Call Hooks at the Top Level”。
将 ProjectButton
组件移出 Projects
的范围,它会很高兴。
发生这种情况是因为您在函数内部使用了钩子,它应该直接在组件内部使用。
如果您将 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>
));
}