如何解决React useEffect钩子带来的无限循环问题
Admin 2022-08-12 群英技术资讯 858 次浏览
这篇文章主要介绍“如何解决React useEffect钩子带来的无限循环问题”,有一些人在如何解决React useEffect钩子带来的无限循环问题的问题上存在疑惑,接下来小编就给大家来介绍一下相关的内容,希望对大家解答有帮助,有这个方面学习需要的朋友就继续往下看吧。React的useEffect Hook可以让用户处理应用程序的副作用。例如:
从网络获取数据:应用程序通常在第一次加载时获取并填充数据。这可以通过useEffect函数实现操作UI:应用程序应该响应按钮点击事件(例如,打开一个菜单)设置或结束计时器:如果某个变量达到预定义值,则内置计时器应自行停止或启动尽管useEffect Hook在React生态系统中很常见,但它需要时间来掌握。因此,许多新手开发人员在配置他们的useEffect函数时,会导致无限循环问题。在本文中,您将了解不同场景下带来的无限循环问题以及如何解决它们。
这是我们今天要学习的内容:
是什么导致无限循环以及如何解决它们:
在依赖项数组中不传递依赖项
如果您的useEffect函数不包含任何依赖项,则会出现一个无限循环。
例如,看看下面的代码:
function App() {
const [count, setCount] = useState(0); //初始化值
useEffect(() => {
setCount((count) => count + 1);
}); //无依赖项
return (
<div className="App">
<p> value of count: {count} </p>
</div>
);
}
如果没有依赖关系,则默认在每个更新周期上触发useEffect。因此,这里的应用程序将在每次渲染时执行setCount函数。因此,这会导致一个无限循环:

是什么导致了这个问题?让我们一步一步来分析这个问题:
count的值。在这里,由于count为0,程序执行useEffect函数useEffect在每个呈现周期中运行,它将重新调用setCount函数为了缓解这个问题,我们必须使用依赖数组,告诉React只有在特定值更新时才调用useEffect。
下一步,像这样附加一个空白数组作为依赖项:
useEffect(() => {
setCount((count) => count + 1);
}, []); //empty array as second argument.
这告诉React在第一次装载时执行setCount函数。

如果你把一个方法传入你的useEffect依赖数组,React会抛出一个错误,表明你有一个无限循环:
function App() {
const [count, setCount] = useState(0);
function logResult() {
return 2 + 2;
}
useEffect(() => {
setCount((count) => count + 1);
}, [logResult]); // 函数作为依赖项
return (
<div className="App">
<p> value of count: {count} </p>
</div>
);
}
在这段代码中,我们将logResult方法传递给useEffect数组。理论上,React只需要在第一次渲染时增加count的值。

是什么导致了这个问题?
如何解决这个问题
一个解决方案是使用useCallback钩子。这允许开发人员记住他们的函数,从而确保引用值保持不变。由于这个参考值是稳定的,React不应该无限地重新渲染UI:
const logResult = useCallback(() => {
return 2 + 2;
}, []); // logResult是缓存的
useEffect(()=> {
setCount((count)=> count+1);
},[logResult]); //没有无限循环错误,因为logResult引用保持不变。
结果:

将数组变量传递给依赖项也会运行一个无限循环。考虑下面的代码示例:
const [count, setCount] = useState(0); //初始值为0。
const myArray = ["one", "two", "three"];
useEffect(() => {
setCount((count) => count + 1); // 和前面一样,增加Count的值
}, [myArray]); // 将数组变量传递给依赖项
在这个块中,我们将myArray变量传入依赖参数。

是什么导致了这个问题?
既然myArray的值在整个程序中都没有改变,为什么我们的代码会多次触发useEffect ?
如何解决这个问题
为了解决这个问题,我们可以使用useRefHook。这将返回一个可变对象,确保引用不会改变:
const [count, setCount] = useState(0);
//提取“current”属性并给它赋值
const { current: myArray } = useRef(["one", "two", "three"]);
useEffect(() => {
setCount((count) => count + 1);
}, [myArray]); //依赖值是稳定的,所以没有无限循环
在useEffect依赖数组中使用对象也会导致无限循环问题。
考虑下面的代码:
const [count, setCount] = useState(0);
const person = { name: "Rue", age: 17 }; //创建一个对象
useEffect(() => {
// 每次增加count的值
// person的值发生了变化
setCount((count) => count + 1);
}, [person]); // 依赖项数组包含一个对象作为参数
return (
<div className="App">
<p> Value of {count} </p>
</div>
);
控制台的结果表明程序是无限循环的:

是什么导致了这个问题?
如何解决这个问题
那么我们如何解决这个问题呢?
这就是usemmo的用武之地。**当依赖关系发生变化时,这个钩子会计算一个记忆的值。**除此之外,因为我们记住了一个变量,这确保了状态的引用值在每次渲染期间不会改变:
// 使用usemo创建一个对象
const person = useMemo(
() => ({ name: "Rue", age: 17 }),
[] //没有依赖关系,所以值不会改变
);
useEffect(() => {
setCount((count) => count + 1);
}, [person]);
如果将错误的变量传递给useEffect函数,React将抛出一个错误。
下面是一个简单的例子:
const [count, setCount] = useState(0);
useEffect(() => {
setCount((count) => count + 1);
}, [count]); //注意,我们将count传递给了这个数组。
return (
<div className="App">
<button onClick={() => setCount((count) => count + 1)}>+</button>
<p> Value of count{count} </p>
</div>
);

是什么导致了这个问题?
如何解决这个问题
要摆脱无限循环,只需像这样使用一个空的依赖数组:
const [count, setCount] = useState(0);
// 只有在组件首次挂载时才更新'count'的值
useEffect(() => {
setCount((count) => count + 1);
}, []);
这将告诉React在第一次渲染时运行useEffect。

尽管React Hooks是一个简单的概念,但是在将它们整合到项目中时,仍然需要记住许多规则。这将确保您的应用程序保持稳定,优化,并在生产过程中不抛出错误。
此外,最近发布的Create React App CLI也会在运行时检测和报告无限循环错误。这有助于开发人员在这些问题出现在生产服务器上之前发现并解决这些问题。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要介绍了如何理解JavaScript中的作用域,帮助大家更好的学习JavaScript,感兴趣的朋友可以了解下
虽然很少会遇到给bind返回的函数做new操作的场景,但面试中还是会涉及到的,所以本文将实现一下兼容new操作的bind写法,顺便学习一下new操作符,需要的可以参考一下
这篇文章给大家分享的是jQuery如何对事件绑定和解绑的相关内容。小编觉得挺实用的,因此分享给大家做个参考,文中的示例代码介绍得很详细,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。
这篇文章主要为大家详细介绍了js实现酷炫倒计时动画,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
之前介绍了http模块的请求与响应的过程,也介绍了TCP协议的客户端与服务端的数据传输,http协议是TCP上层协议。这里创建了一个简单的web服务器,并对提交表单数据进行处理,根据了不起的Node.js一书总结。POST方法提交表单数据之前也总结过,向服务器提交数据需要使用POST方法,GET方法的请求信息都在查询字符串中,没有请求体,而POST方法的传输的数据都在请求体中,故提交表单数
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008