![](/img/trans.png)
[英]useEffect infinite loop when updating state and including dependency array
[英]useEffect in React runs in an infinite loop, when an array is passed as a dependency
當以下代碼在 React 組件中運行時,會導致無限循環。 為什么將數組作為依賴項傳遞給useEffect
(在本例中為args
)會導致這種情況發生? 我怎樣才能阻止無限循環的發生? 代碼應該只運行一次。
我讀過我可以使用[args.length]
來阻止這種情況發生,但是 ESLint 規則react-hooks/exhaustive-deps
會拋出一個錯誤,所以我想避免這樣做。
import React, { useEffect, useState } from 'react';
export default function Home() {
const args = ['a'];
const [value, setValue] = useState(['b']);
useEffect(() => {
setValue(['c']);
}, [args]);
console.log('value', value);
}
請注意,在上面的代碼中,我在useEffect
回調中根本沒有使用或修改args
。
如果我將args
的值更改為字符串,例如const args = 'a'
,那么就沒有無限循環。 所以當依賴是一個數組時,問題似乎發生了。
問題是對args
任何更改都會導致您的效果運行。 此時您setValue(args)
以便args
再次更改。 這將導致您的效果再次運行......因此是一個無限循環。
如果您將args
設置為與之前相同的字符串,如果它們按照 react 檢測更改的方式匹配,則不會將其注冊為更改。 這不適用於數組或對象。 {test: 'a'} !== {test: 'a'}
和['a'] !== ['a']
但是'a' === 'a'
和1 === 1
。
我也遇到了你的問題。 我最終禁用了react-hooks/exhaustive-deps
規則。 但我有更多的數據給你。 我努力嘗試使用這條規則一段時間。
我發表的這篇文章與您的問題非常相似。 最終結果是您應該使用setState
作為函數(即示例中的setState(oldState => oldState)
),此時舊狀態不需要是依賴項或useReducer
也可以產生相同的效果。
但是,這兩種方法都不可能完全符合您可能嘗試做的事情,這會產生更多問題,如我稍后發表的這篇文章中所見。 如果他們是純潔的,那你就沒事了。
第1 篇文章中的第 4 個解決方案描述了如何積極避免這個問題,但最終我決定使用react-hooks/exhaustive-deps
規則並在我有意刪除我不想要的依賴項時逐行禁用它。 我不同意這應該是所有這一切之后的規則。
您嘗試做的問題是平衡 React 的useState
和useReducer
要求與詳盡的 deps 要求。 我認為這需要做很多工作來使這些需求比實際生產力更滿意。
使用useRef
為我解決了這個問題:
const args = useRef(['a']);
const [value, setValue] = useState(['b']);
useEffect(() => {
setValue(['c']);
}, [args]);
console.log('value', value);
並且args
的值可以在useEffect
回調中使用,使用args.current
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.