realdennis

May 20, 2021

10 min read

用八二法則寫 custom react-hooks

根據八二法則,只需要兩成的功就能滿足八成的事,那我們來用兩成的 built-in hooks 來封裝八成我們會用到的 custom hooks 吧!

寫在文前

內建的 hooks

https://zh-hant.reactjs.org/docs/hooks-reference.html
  • 控 state 的useState useReducer useContext
  • 控 Effect 的useEffect useLayoutEffect
  • 控 ref 的useRef useImperativeHandle
  • 優化用的(useMemo useCallback
  • Debug 用( useDebugValue, 我沒用過)

useState & useEffect 在幹嘛?

A trivial component use hook

會這兩個 hook 還能幹嘛?

  1. 優雅地拿外部(window)滾動狀態——useWindowScroll
  2. 優雅地拿外部(window)的 size ——useWindowSize
  3. 優雅地拿外部(裝置)電量狀態——useBattery
  1. (effect) attach event
  2. (cleanup) detach event
注意 L27,comparedArray 依然是 [] ,所以只會在 mounted 時 attach , unmounted detach event。
  1. (effect) attach window event, resize
  2. (cleanup) 把上述 event detach 掉。
注意 L78 ,comparedArray 依然是 [] ,所以只會在 mounted 時 attach , unmounted detach event。
  1. (effect) attach events,包括 chargingchange, chargintimechange, dischargingtimechange, levelchange
  2. (cleanup) 把上述四個 event detach 掉。
  • 註冊 event 到 react element (onClick),react 在 lifecycle 結束後會幫你清除掉。
  • 註冊在外部的(addEventListener),如果你沒有手動清除,它就會一直掛在那,這種就是 side-effect 。

useRef

function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}

繼續我們的 code reviewing 之旅吧

  1. 優雅地改 document title —— useTitle
  2. 優雅地將 throttle 密集變動的 props ——useThrottle
ref: useThrottle docs
  1. value change,設定一個計時器幫我更新(也許200ms)
  2. 若 1. 還沒執行 timer callback,有 value 的 update ,則進入 L23-25,將其設為下一個被設定的 nextValue
  3. 若 1. 2. 還沒執行,有新 value update,則進入 L23–25 ,nextValue 被 override 為最新值(意味著 2. 被 throttle 掉囉)

尾聲

If any interest, 👉 https://realdennis.me.

Love podcasts or audiobooks? Learn on the go with our new app.