React hook useEffect 永远/无限循环连续运行
Posted
技术标签:
【中文标题】React hook useEffect 永远/无限循环连续运行【英文标题】:React hook useEffect runs continuously forever/infinite loop 【发布时间】:2019-04-14 01:19:03 【问题描述】:我正在尝试新的React Hooks 的useEffect
API,它似乎一直在无限循环中运行!我只希望useEffect
中的回调运行一次。这是我的代码供参考:
点击“Run code sn -p”可以看到“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>
【问题讨论】:
【参考方案1】:这是因为 useEffect
在每次渲染后触发,在这种功能组件的情况下,这是对 Counter()
函数的调用。当您在 useEffect
中执行从 useState
返回的 setX
调用时,React 将再次渲染该组件,并且 useEffect
将再次运行。这会导致无限循环:
Counter()
→ useEffect()
→ setCount()
→ Counter()
→ useEffect()
→ ...(循环)
要使您的 useEffect
只运行一次,请传递一个空数组 []
作为第二个参数,如下面修改后的 sn-p 所示。
第二个参数的目的是在数组参数中的任何值发生变化时告诉 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的信息。
【讨论】:
这是解决方案,但是如果您使用的是react-hooks
eslint 插件。这将被exhaustive-deps
规则标记。看来正确的解决方案是使用useCallback
钩子,更多讨论在这里:github.com/facebook/react/issues/14920#issuecomment-471070149以上是关于React hook useEffect 永远/无限循环连续运行的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 React hooks 和 Redux 从 useEffect 执行 store.unsubscribe
在 React Hooks useEffect cleanup 中取消 Axios REST 调用失败
UseEffect - React Hook useEffect 缺少依赖项:
有条件地调用 React Hook “useEffect”。在每个组件渲染中,必须以完全相同的顺序调用 React Hooks