使用 useEffect 和 reactStrictMode:優化 React 元件的效能和可靠性
P粉739706089
2023-08-18 16:06:50
<p>我有一個挑戰,我想把數組的一部分加載到一個名為“loadedData”的新數組中,並且只顯示加載的數據,因為組件非常重。 </p>
<p>然而,在第一次加載時,我遇到了很多問題,因為useEffect似乎搞砸了它。第一次載入會發生兩次,每次渲染都會將第一個資料推送到數組中一次。如果我刪除“reactStrictMode”,它會按照預期工作,但我不想在不理解後果的情況下“作弊”。比我更好地理解這個問題的人把它放在那裡是有原因的.. </p>
<p>在初始加載期間,isLoading狀態無法阻止第二次運行-這是我在其他與此問題相關的線程中得到的建議。 </p>
<p>有人知道為什麼第一個useEffect忽略isLoading狀態以及如何處理嗎? </p>
<pre class="brush:php;toolbar:false;">// 嘗試載入可見部分,但不要載入更多
const [loadedData, setLoadedData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const addMoreData = async () => {
if (loadedData.length >= data.length) return;
const startIndex = loadedData.length;
const preferredLoadLength = 1;
const endIndex = startIndex preferredLoadLength;
const newData = data.slice(startIndex, endIndex);
setLoadedData((prev) => [...prev, ...newData]);
};
// 檢查掛載和獲取數據後是否已將表格滾動到底部並立即需要獲取更多數據
useEffect(() => {
const { scrollHeight, scrollTop, clientHeight } = tableContainerRef.current;
if (
scrollHeight == clientHeight &&
scrollTop == 0 &&
loadedData.length < data.length
) {
const addNewDataFunction = async () => {
if (isLoading) {
return;
}
setIsLoading(true);
await addMoreData();
setIsLoading(false);
};
addNewDataFunction();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data.length, loadedData.length, isLoading]);</pre>
<p><br /></p>
你可以在
addMoreData
函數中簡單地更改這一行為
這將使狀態根據當前渲染時的值進行更新,因為第二次
useEffect
運行時元件尚未重新渲染,所以第一個元件所做的更改尚未反映出來,因此loadedData
尚未更新。當你使用函數形式進行更新時,
prev
是狀態的即時值,在開發中使用嚴格模式時,你會遇到這種情況是正常的。最後,擺脫
isLoading
,它不會幫助修復這個問題。注意:在啟用嚴格模式時,使用setState的函數形式更推薦,但在
useEffect
中不建議使用,因為當元件掛載時,這個鉤子會運行兩次。此外,當你在依賴數組中包含
data.length
和loadedData.length
時,這將使useEffect
在這些值中的任何一個發生變化時都會觸發。