![](/img/trans.png)
[英]React Hooks useCallback and useEffect causes infinite loop in react application
[英]React Hooks useCallback dependency infinite loop
我目前在組件安裝時獲取我的數據一次,然后在用戶單擊按鈕時獲取。 但是,如果請求正在進行,我想停止按鈕獲取,這就是我更新isFetching
state 的原因。
但是,我需要將isFetching
添加到useCallback
依賴項以刪除警告,如果這樣做,則會觸發無限獲取循環。
這是我的代碼:
import { useCallback, useEffect, useRef, useState } from 'react';
export const MyComponent = () => {
const isMounted = useRef(true);
const [isFetching, setIsFetching] = useState(false);
const [data, setData] = useState(null);
// Can also be called from the button click
const getMyData = useCallback(() => {
if (isFetching) return;
setIsFetching(true);
fetch('get/my/data')
.then((res) => {
if (isMounted.current) {
setData(res.data);
}
})
.catch((err) => {
if (isMounted.current) {
setData("Error fetching data");
}
})
.finally(() => {
if (isMounted.current) {
setIsFetching(false);
}
});
}, []); // isFetching dependency warning as is, if added then infinite loop
useEffect(() => {
isMounted.current = true;
getMyData();
return () => {
isMounted.current = false;
};
}, [getMyData]);
return (
<div>
<button onClick={getMyData}>Update data</button>
<p>{data}</p>
</div>
);
};
我知道有多個像這樣的問題,但我無法刪除警告或無限循環,同時仍在檢查組件是否已安裝。
將isFetching
轉換為 ref,因此它的值不會是 function 的依賴項:
const { useCallback, useEffect, useRef, useState } = React; const MyComponent = () => { const isMounted = useRef(true); const isFetching = useRef(false); const [data, setData] = useState([]); // Can also be called from the button click const getMyData = useCallback(() => { console.log('call'); if (isFetching.current) return; isFetching.current = true; fetch('https://cat-fact.herokuapp.com/facts').then(res => res.json()).then(res => { if (isMounted.current) { setData(res); } }).catch((err) => { if (isMounted.current) { setData("Error fetching data"); } }).finally(() => { if (isMounted.current) { isFetching.current = false; } }); }, []); // isFetching dependency warning as is, if added then infinite loop useEffect(() => { isMounted.current = true; getMyData(); return () => { isMounted.current = false; }; }, [getMyData]); return ( <div> <button onClick={getMyData}>Update data</button> <ul> { data.map(({ _id, text }) => ( <li key={_id}>{text}</li> )) } </ul> </div> ); }; ReactDOM.render( <MyComponent />, root );
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.