跳至主要内容

React Basic

Re-Render

  • 時機:
    1. 只要 component 的 state 改變就會觸發 re-render
    2. 當 component re-render 的時候,預設 child component 也會 re-render
信息

在進行效能優化時,除了 memo() 之外,可參考 Before You Memo

useEffect

延伸閱讀:

  • 對於 React 來說所有的 function component 都是 pure function,應該只用來處理 propsstate,最後回傳一個 JSX
  • React 的 side-effects 通常用於「跳出」React 程式碼並與某些外部系統同步。包括瀏覽器 API、第三方小工具、網路...等
  • useEffect 預設會在每次 render 執行

Dependency Array

  • useEffect 只會在陣列內容變更時被執行,節省效能
import { useEffect } from "react";

function App() {
const [counter, setCounter] = useState(0);

useEffect(() => {
// useEffect 沒有 dependency array
// 每次 render 都會觸發
console.log("Render");
});

useEffect(() => {
// useEffect 的 dependency array 沒有使用到任何相依的 states 或 props
// 因此只在第一次 render 觸發
console.log("Init");
}, []);

useEffect(() => {
// useEffect 的 dependency array 有 counter
// 因此只在 counter 變動時觸發
console.log(`Counter: ${counter}`);
}, [counter]);

return (
<div>
<p>{counter}</p>
<button onClick={() => setCounter(counter + 1)}>-</button>
<button onClick={() => setCounter(counter - 1)}>+</button>
</div>
);
}

Cleanup Function

  • Cleanup Function 會在下一次的 useEffect 執行前執行
  • 讓 component unmount 時執行需要 cleanup 的行為,例如:websocket 連線、clearInterval ...等等
import React, { useState, useEffect } from "react";

function App() {
const [counter, setCounter] = useState(0);
console.log("Execute");

useEffect(() => {
console.log(`Counter: ${counter}`);
return () => {
console.log(`Cleanup: ${counter}`);
};
});

return (
<div>
{console.log("Render")}
<p>{counter}</p>
<button onClick={() => setCounter(counter + 1)}>-</button>
<button onClick={() => setCounter(counter - 1)}>+</button>
</div>
);
}
# 第一次 Render
Execute
Render
Counter 0

# 元件更新
Execute
Render
Cleanup 0 // 上一次 useEffect 取得的值
Counter 1 // 本次執行的 useEffect 取得的值

# 元件 unmount 時
Cleanup 1

參考資料