React Hooksで保持する参照を毎回初期化しないようにする

React Hooksを使ってオブジェクトへの参照を保持する場合、初期値を伴うuseRef()を使うと次のようになる:

const MyComponent: React.FC<Props> = () => {
  const instanceRef = React.useRef(createInstance())
  return ...
}

こうするとコンポーネントが再レンダーされるたびに毎回初期化を行ってしまって無駄な処理になるほか、初期化に副作用があったりすると厄介になる。

useState()によって初期化するとこの問題が回避できる:

// useRef () will initialize a reference on every render.
// useState () allows initialization only on first render.
// https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
function useLazyInitializableRef<T>(create: () => T): T {
  const [value] = React.useState(create)
  return value
}

const MyComponent: React.FC<Props> = () => {
  const instance = useLazyInitializableRef(createInstance)
  return ...
}

(ちなみにtsx内ではアロー関数にジェネリクスが使えない)

useState()の引数に渡した関数は初回レンダー時のみ実行され、後続のレンダーでは無視される

react-useにあるuseMeasure()の実装を見ていて気づいた。