iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0
Modern Web

React 從 0.5 到 1系列 第 13

[鐵人賽 Day13] 來讀 Hooks FAQ 文件吧!- Effect dependencies 太常改變,可以做些什麼嗎?

  1. 什麼狀況下 code 裡面會看到不新鮮的 props 跟 state?

以下案例在 state 已經更新的狀態下,仍然會取到舊的值。原因是任何在元件內的函式(包含 event handlers 與 effects )看到的 props 與 state 都是從他們被建立的當下那組 render 結果裡取來的。

如果你按下 “Show alert” 之後立刻點擊 "Click me" 去更動 count state 的數量,“Show alert” 印出來的 count 會是你點擊 “Show alert” 按鈕當下的數字,而不是你點擊 "Click me" 之後更新過的數字。而如果你是有意要去讀取到非同步 callback 裡最新的 state 結果,你可以把他保存在 ref 裡。

function Example() {
	// 元件裡有一個 count 的 state,初始值是 0 
  const [count, setCount] = useState(0);

  function handleAlertClick() {
		// 在觸發點擊的當下,會等待 10 秒之後,印出當下的 count 數量
    setTimeout(() => {
      alert('You clicked on: ' + count);
    }, 10000);
  }

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
      <button onClick={handleAlertClick}>
        Show alert
      </button>
    </div>
  );
}

除了上面的案例,其他可能的原因還有:你使用了依賴 ”dependency array“ 的優化方法,但沒有正確的指定所有 dependencies。

  1. Effect dependencies 太常改變,可以做些什麼嗎?

有時候你的 effect 使用的 state 可能頻繁改變,例如底下的 count。把 count 放進 dependencies 是標準做法,但這會在每次 count 改變的時候,reset interval。

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const counter = setInterval(() => {
      setCount(count + 1);
    }, 1000);
    return () => clearInterval(counter);
  }, [count]);

  return <h1>{count}</h1>;
}

要解決這個缺點,我們可以使用 setState 的 Functional updates,就不需要 reference 當下的 state 值。

// 你可以傳一個 function 給 setState,這個 function 會接收到前一個值,然後回傳更新過的值。
<button onClick={() => setCount(prevCount => prevCount - 1)}>minus</button>

把它帶入案例裡,就是這樣子。因為我們不需要再依靠 count 變數,而是使用 setState 就可以拿到同樣的內容並且對它更新。

*dependencies 的空值([ ]),代表這個 effect 只會在 component mount 的時候跑一次。

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const counter = setInterval(() => {
      setCount(prevCount => prevCount + 1); 
    }, 1000);
    return () => clearInterval(counter);
  }, []);

  return <h1>{count}</h1>;
}

上一篇
[鐵人賽 Day12] 來讀 Hooks FAQ 文件吧! - Hooks 取代 render props 跟 HOC 的用法了嗎?
下一篇
[鐵人賽 Day14] 來讀 Hooks FAQ 文件-lifecycle methods 如何對照到 Hooks?
系列文
React 從 0.5 到 115

尚未有邦友留言

立即登入留言