[英]React Hooks Exhaustive-deps async infinite Loop
我有以下組件:
import React, { useState, useEffect } from "react";
const App = () => {
const [data, setData] = useState<null | any[]>(null);
const [checked, setChecked] = useState(false);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
(async () => {
if (data) {
// Could do something else here if data already exsisted
console.log("Data exists already");
}
const ret = await fetch("https://jsonplaceholder.typicode.com/users?delay=1000", { cache: "no-store" });
const json = await ret.json();
setData(json);
setLoading(false);
})();
}, [checked]);
return (
<>
<h1>useEffect Testing {loading && " ⌛"}</h1>
<hr />
<input type="checkbox" checked={checked} onChange={(e) => setChecked(e.target.checked)} />
<pre style={{ fontSize: "0.8em" }}>{JSON.stringify(data)}</pre>
</>
);
};
export default App;
Currently, my if(data)
is pointless however if I wanted to check the current data
state and then run an asynchronous function based on the state the eslint(react-hooks/exhaustive-deps) tells me the hook is missing the data
dependency,它是。 當我將數據添加到導致無限循環的依賴項列表時,問題就出現了。
知道如何解決這個問題嗎? 感覺它應該是相當簡單的模式,但是我發現的所有建議都使用擴展的setState(prev => prev + 1)
重載,在這種情況下對我沒有幫助。
您正在設置data
並在效果中讀取它。 除非您手動停止它,否則這將導致您陷入無限循環。 這里有一些解決方案。
如果有數據則返回而不是修改它:
useEffect(() => {
setLoading(true);
(async () => {
if (data) {
// Could do something else here if data already exsisted
console.log("Data exists already");
return;
}
const ret = await fetch("https://jsonplaceholder.typicode.com/users?delay=1000", { cache: "no-store" });
const json = await ret.json();
setData(json);
setLoading(false);
})();
}, [checked, data]);
消除您對設置它的效果中的data
的依賴(我會做什么):
useEffect(() => {
setLoading(true);
(async () => {
const ret = await fetch("https://jsonplaceholder.typicode.com/users?delay=1000", { cache: "no-store" });
const json = await ret.json();
setData(json);
setLoading(false);
})();
}, [checked]);
useEffect(() => {
if (data) {
// Could do something else here if data already exsisted
console.log("Data changed and exists!");
}
}, [data]);
或者您可以手動執行一些停止無限循環的操作。
useEffect(() => {
if (loading || data) {
console.log('Do something with loading or data, but do not modify it!')
return;
}
setLoading(true);
(async () => {
const ret = await fetch("https://jsonplaceholder.typicode.com/users?delay=1000", { cache: "no-store" });
const json = await ret.json();
setData(json);
setLoading(false);
})();
}, [checked, data]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.