なぜgetElementByIdやquerySelectorではなく、useRefを使うのか
ここで言うuseRef
とは次のように利用している場合のuseRef
を指しています。
const ref = useRef(null);return <div ref={ref} />;
なぜ getElementById や querySelector ではなく、useRef を使うのか
- 意図しない DOM ノードが選択されるケースを防ぐため
React を用いた多くのプロジェクトでは様々なライブラリを使用します。 その中で挿入されたクラス名や ID が意図せず重複し、誤った選択がされるケースを useRef を用いれば防ぐことができます。
- 単一方向のデータフローに適しているため
useRef では、親コンポーネントでノード参照を定義し、それらを子コンポーネントに放り投げることができます。
それに対して、getElementById や querySelector は完全にデータフローを無視することができてしまいます。 また分割された子コンポーネントなどを参照する場合、親コンポーネントと子コンポーネントは互いに指定される ID を持っている必要があります。
また querySelector の場合、取得される値は immutable であり、現在の NodeTree に存在するか判定することができません。
useRef の用途
- フォーカス、テキスト選択、またはメディア再生の管理
- 命令型アニメーションのトリガー
- サードパーティの DOM ライブラリとの統合
Reference calls による DOM ノードの管理は避けられるべき
Reference calls による DOM ノードの管理とは、getElementById、useRef、createRef などのことです。
同じ状態を複数のコンポーネントが所持している場合、これらの状態を共通化できる親要素まで持ち上げることで、レンダリングを抑制し、多くの場合ロジックを単純化することができるため、状態を持ち上げることは一般に推奨されています。ですが useRef を用いると、その参照の状態をそのコンポーネント自体またはその子要素で管理することになり、 無駄なレンダリングを発生する原因となりえます。そのため Reference calls による DOM ノードの管理は極力避けられるべきです。
useRef の用途にない使い方をしようとしている場合、useRef を用いず親要素によって状態を管理できないかよく考えましょう。