javascript Uncaught Invariant Violation:渲染的钩子比上一次渲染时更多
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/55622768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Uncaught Invariant Violation: Rendered more hooks than during the previous render
提问by timothym
I have a component that looks like this (very simplified version):
我有一个看起来像这样的组件(非常简化的版本):
const component = (props: PropTypes) => {
const [allResultsVisible, setAllResultsVisible] = useState(false);
const renderResults = () => {
return (
<section>
<p onClick={ setAllResultsVisible(!allResultsVisible) }>
More results v
</p>
{
allResultsVisible &&
<section className="entity-block--hidden-results">
...
</section>
}
</section>
);
};
return <div>{ renderResults() }</div>;
}
When I load the page this component is used on, I get this error: Uncaught Invariant Violation: Rendered more hooks than during the previous render.I tried to find an explanation of this error, but my searching returned no results.
当我加载使用此组件的页面时,出现此错误:Uncaught Invariant Violation: Rendered more hooks than during the previous render.我试图找到此错误的解释,但我的搜索未返回任何结果。
When I modify the component slightly:
当我稍微修改组件时:
const component = (props: PropTypes) => {
const [allResultsVisible, setAllResultsVisible] = useState(false);
const handleToggle = () => {
setAllResultsVisible(!allResultsVisible);
}
const renderResults = () => {
return (
<section>
<p onClick={ handleToggle }>
More results v
</p>
{
allResultsVisible &&
<section className="entity-block--hidden-results">
...
</section>
}
</section>
);
};
return <div>{ renderResults() }</div>;
}
I no longer get that error. Is it because I included the setStatefunction within the jsx that is returned by renderResults? It would be great to have an explanation of why the fix works.
我不再得到那个错误。是不是因为我setState在 jsx 中包含了由 返回的函数renderResults?最好能解释一下此修复程序的工作原理。
采纳答案by Jake Worth
The fix works because the first code sample (the erroring one) invokes a function inside onClick, while the second (the working one) passes a function to onClick. The difference is those all-important parentheses, which in JavaScript mean 'invoke this code'.
该修复程序有效,因为第一个代码示例(出错的那个)调用了 内部的一个函数onClick,而第二个(工作中的)将一个函数传递给了onClick。区别在于那些非常重要的括号,它们在 JavaScript 中的意思是“调用此代码”。
Think of it this way: in the first code sample, every time componentis rendered, renderResultsis invoked. Every time that happens, setAllResultsVisible(!allResultsVisible), rather than waiting for a click, is called. Since React performs the render on its own schedule, there's no telling how many times that will happen.
可以这样想:在第一个代码示例中,每次component渲染、renderResults调用。每次发生这种情况时setAllResultsVisible(!allResultsVisible),都会调用 ,而不是等待点击。由于 React 按照自己的时间表执行渲染,因此不知道会发生多少次。
From the React docs:
来自 React 文档:
With JSX you pass a function as the event handler, rather than a string.
使用 JSX,您可以传递一个函数作为事件处理程序,而不是一个字符串。
Note: I wasn't able to get this exact error message when running the first code sample in a sandbox. My error referred to an infinite loop. Maybe a more recent version of React produces the error described?
注意:在沙箱中运行第一个代码示例时,我无法获得此确切的错误消息。我的错误是指无限循环。也许更新版本的 React 会产生所描述的错误?
回答by Ertan Hasani
You can simply change your onlick event add () =>before setAllResultsVisible
您可以在 setAllResultsVisible() =>之前简单地更改您的 onlick 事件添加
<p onClick={() => setAllResultsVisible(!allResultsVisible) }>
More results v
</p>
and it will work perfectly
它会完美地工作

