UseEffect无限循环/永远运行,即使状态没有改变



我目前正在useEffect内放置一个API GET请求调用。这里的想法是每次状态被修改时都要"重新渲染"列表。

const[superheroes, setSuperheroes] = useState([]);
useEffect(() => {
apiCall('/superheroes', { method: 'GET'})
.then(response => {
response.json().then(response => {
setSuperheroes(response);
}).catch(x=> console.log("ERROR: " + x))
})
}, [superheroes])

简单地这样做将导致无限调用循环,即使superheroes状态尚未改变。

我能得到一个清楚的解释为什么会发生这种情况吗?

编辑:澄清。我故意不使用空数组作为useEffect()的第二个参数,因为我不想运行它一次。

当您在useEffect中设置一个新数组(也是一个对象)时,会发生这种情况

function DoSomethingCrazy() {
const [superheroes, setSuperheroes] = React.useState([]);
React.useEffect(() => {
console.log("i have arrived at the party!");
setSuperheroes(["123123"]);
}, [superheroes]);
return <div>stuff goes here</div>;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<DoSomethingCrazy />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>

尝试将一个空数组放到useEffect中,这样它只运行一次:

useEffect(() => {
apiCall("/superheroes", { method: "GET" }).then((response) => {
response
.json()
.then((response) => {
setSuperheroes(response);
})
.catch((x) => console.log("ERROR: " + x));
});
}, []);

每次超级英雄被改变时都会触发此效果。因为useEffect总是第一次执行,然后根据代码在ajax调用时获得的依赖数组,并且响应的superheroes被setSuperheroes更改,然后因为是useEffect的依赖项,整个过程将再次发生。

这里你没有重新渲染,你只是通过ajax重新获取。

React使用shallow compare比较新状态和当前状态

当API调用成功时,setSuperheroes将调用一个新的数组,并且state将有一个新的值。对于shallow compare,新状态总是不同于当前状态,所以组件总是重新渲染。

相关内容

  • 没有找到相关文章

最新更新