Home Article Practice useEffect无限循环

useEffect无限循环

2024-06-30 12:38  views:238  source:许某    

当useEffect的第二个参数传数组传一个依赖项,当依赖项的值发生变化,都会触发useEffect执行。
请看下面的例子:
App组件显示了一个项目列表,状态和状态更新函数来自与useState这个hooks,
通过调用useState,来创建App组件的内部状态。
初始状态是一个object,其中的hits为一个空数组,目前还没有请求后端的接口。
import React, { useState } from 'react';
function App() {
const [data, setData] = useState({ hits: [] });
return (
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
);
}
export default App;
为了获取后端提供的数据,接下来将使用axios来发起请求,
同样也可以使用fetch,这里会使用useEffect来隔离副作用。
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [data, setData] = useState({ hits: [] });
useEffect(async () => {
const result = await axios(
'urlurlurl',
);
setData(result.data);
});
return (
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
);
}
export default App;
在useEffect中,不仅会请求后端的数据,
还会通过调用setData来更新本地的状态,这样会触发view的更新。
但是,运行这个程序的时候,会出现无限循环的情况。
useEffect在组件mount时执行,但也会在组件更新时执行。
因为我们在每次请求数据之后都会设置本地的状态,所以组件会更新,
因此useEffect会再次执行,因此出现了无限循环的情况。我们只想在组件mount时请求数据。
我们可以传递一个空数组作为useEffect的第二个参数,这样就能避免在组件更新执行useEffect,
只会在组件mount时执行。
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [data, setData] = useState({ hits: [] });
useEffect(async () => {
const result = await axios(
'urlurlurl',
);
setData(result.data);
}, []);
return (
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
);
}
export default App;
useEffect的第二个参数可用于定义其依赖的所有变量。
如果其中一个变量发生变化,则useEffect会再次运行。
如果包含变量的数组为空,则在更新组件时useEffect不会再执行,因为它不会监听任何变量的变更。
再看这个例子:
业务场景:需要在页面一开始时得到一个接口的返回值,取调用另一个接口。
我的思路是,先设置这个接口的返回值为data=[], 等到数据是再去请求另一个接口,
即data作为useEffect的第二个参数传入。
但是不知道为什么会造成死循环,拿不到我们想要的结果。
直到在官网看到这个例子:
知道useEffect会比较前一次渲染和后一次渲染的值,然后我就在想,
如果我所设置的data=[],那么即使我后一次渲染的data也为[],那么[]===[]为false,
所以才会造成useEffect会一直不停的渲染,
所以我把data的初始值改为undefined,试了一下果然可以。
结论:useEffect的不作为componentDidUnmount的话,
传入第二个参数时一定注意:第二个参数不能为引用类型,
引用类型比较不出来数据的变化,会造成死循环



Disclaimer: The above articles are added by users themselves and are only for typing and communication purposes. They do not represent the views of this website, and this website does not assume any legal responsibility. This statement is hereby made! If there is any infringement of your rights, please contact us promptly to delete it.

字符:    改为:
去打字就可以设置个性皮肤啦!(O ^ ~ ^ O)