loading...
上次更新: 2023-05-22
- 在 input 輸入數字後,下面列表會顯示此 input 值加1、加2、加3的結果
- 點擊 toggle theme 按鈕可把畫面轉為亮/暗色模式

<List/>getData function,我們就假裝它裡面會呼叫 api 獲取資料並 return 這筆資料getData return 的資料會依 input 值而改變getData 作為 props 傳到子元件 <List/>import List from './List';
export default function App() {
const [input, setInput] = useState(0);
const [themeDark, setThemeDark] = useState(false);
const style = {
color: themeDark ? '#fff' : '#1b1b1b',
background: themeDark ? '#1b1b1b' : '#fff',
};
// 假裝它會呼叫 api、回傳資料
const getData = () => {
// getData return 的資料會依 input 值而改變
return [input + 1, input + 2, input + 3];
};
return (
<div className="App" style={style}>
<input
value={input}
type="number"
onChange={(e) => {
setInput(parseInt(e.target.value));
}}
/>
<button
onClick={() => {
setThemeDark(!themeDark);
}}
>
Toggle Theme
</button>
// getData 作為 props 傳入
<List getData={getData} />
</div>
);
}getData 這個 props,呼叫並使用 getData 回傳的資料getData 改變時,就重新用 setArray 設置畫面所顯示的 list 項目,並印出 "get data" 文字export default function List(props) {
const { getData } = props;
const [array, setArray] = useState([]);
useEffect(() => {
setArray(getData());
console.log('get data');
}, [getData]);
return (
<>
{array.map((item) => {
return <li key={item}>{item}</li>;
})}
</>
);
}getItem function 會跟著改變,因此在 <List/> 裡面的 useEffect 會被觸發,執行 getData() ,並印出 "get data",這很好理解useEffect ,印出 "get data"這代表 getData 在點擊按鈕時也改變了,原因是點擊按鈕時會改變 themeDark 狀態,然後觸發父元件的 re-render;父元件重新 render 時,就會創造一個新的 getData function。
使用 useCallback
useCallback 用法跟 useMemo 一樣,有兩個參數:// 原本寫法
const getData = () => {
return [input + 1, input + 2, input + 3];
};
// 改為
const getData = useCallback(() => {
return [input + 1, input + 2, input + 3];
}, [input]);useCallback 跟 useMemo 比較
useMemo 不能傳入參數,而 useCallback 可以useCallback useMemo 都會接收一個 function,但 useMemo 會回傳此 function 的回傳值,而 useCallback 會回傳此 functionuseCallback(fn, [deps]) 就相當於 useMemo(() => fn, [deps])// 也可用 useMemo 寫法
const getData = useMemo(() => {
return () => {
return [input + 1, input + 2, input + 3];
};
}, [input]);