博客 / 詳情

返回

在react hooks中,當useEffect依賴自身來更新自己時,遭遇死循環如何解決?

提出問題

觀察如下代碼,我們需要依賴words來更新自身,所以需要將words加入useEffect的依賴中。更新words觸發useEffectuseEffect再次更新words,然後就產生了死循環。

function App() {
  const [value, setValue] = useState('');
  const [words, setWords] = useState([
    {
      id: 0,
      text: 'like',
      correct: false,
    },
  ]);

  useEffect(() => {
    const items = value.split(' ');
    
    // 我們需要用words來更新自身
    const nextWords = words.map((word) => {
      return {
        ...word,
        correct: word.text === items[index],
      };
    });

    setWords(nextWords);
  }, [value, words]);

  return (
    <>
      <input
        type="text"
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
    </>
  );
}

分析問題

為了跳出useEffect的死循環,問題的關鍵是,我們不能在useEffect重更新依賴數組中的東西,否則必定產生死循環。那如何避免更新自己的依賴呢?答案是用一個新的變量來存儲。

解決方案

我們創建了一個新的nextWords來保存更新後的words,避免了更新依賴項死循環的問題。

function App() {
  const [value, setValue] = useState('');
  const [words, setWords] = useState([
    {
      id: 0,
      text: 'like',
      correct: false,
    },
  ]);
  const [nextWords, setNextWords] = useState([])

  useEffect(() => {
    const items = value.split(' ');
    
    // 我們需要用words來更新自身
    const nextWords = words.map((word) => {
      return {
        ...word,
        correct: word.text === items[index],
      };
    });
    
    // 這裏不會導致死循環,因為nextWords並非依賴項
    setNextWords(nextWords);
  }, [value, words]);

  return (
    <>
      <input
        type="text"
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
    </>
  );
}
user avatar webxejir 頭像 aresn 頭像 gaiya_68f1e7ba5b140 頭像
3 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.