簡體   English   中英

當數組作為依賴項傳遞時,React 中的 useEffect 在無限循環中運行

[英]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 的useStateuseReducer要求與詳盡的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM