React钩子useEffect永远/无限循环连续运行



我正在试用新的React Hooks的useEffectAPI,它似乎永远在无限循环中运行!我只希望useEffect中的回调运行一次。这是我的代码供参考:

点击"Run code snippet"可以看到"Run useEffect"字符串被无限打印到控制台

function Counter() {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
console.log('Run useEffect');
setCount(100);
});
return (
<div>
<p>Count: {count}</p>
</div>
);
}
ReactDOM.render(<Counter />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>

之所以会发生这种情况,是因为每次渲染后都会触发useEffect,在功能组件的情况下,这是对Counter()函数的调用。当您在useEffect中执行从useState返回的setX调用时,React将再次呈现该组件,useEffect将再次运行。这导致了一个无限循环:

Counter()useEffect()setCount()Counter()useEffect()→ ...(环路(

要使useEffect只运行一次,请传递一个空数组[]作为第二个参数,如下面修改后的代码段所示。

第二个参数的目的是告诉React数组参数中的任何值何时发生变化:

useEffect(() => {
setCount(100);
}, [count]); // Only re-run the effect if count changes

您可以将任意数量的值传递到数组中,并且useEffect将仅在其中任何一个值更改时运行。通过传递一个空数组,我们告诉React不要跟踪任何更改,只运行一次,有效地模拟了componentDidMount

function Counter() {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
console.log('Run useEffect');
setCount(100);
}, []);
return (
<div>
<p>Count: {count}</p>
</div>
);
}
ReactDOM.render(<Counter />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>

阅读更多关于useEffect的信息。

您正在运行一个无限循环,因为没有为编写的useEffect提供依赖项。

为了避免使用useEffect挂钩时出现无限循环,请确保提供一个包含效果所依赖的所有变量的依赖数组

例如,如果您只想在组件装载时运行一次效果,那么您可以传递一个空的依赖数组,如下所示:

useEffect(() => {
// effect code here
}, [])

如果您希望在特定变量发生更改时运行效果,您可以将该变量包含在依赖数组中:

const [count, setCount] = useState(0);
useEffect(() => {
// effect code here
}, [count])

相关内容

  • 没有找到相关文章

最新更新