Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Useref in react theory question

2025年10月03日に「Dev.to」が公開したITニュース「Useref in react theory question」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

useRefはReactのフックで、再レンダリングしても保持される変更可能な値(.current)を返す。値が更新されても画面は再描画されない点がuseStateと異なり、DOM要素への直接アクセスや、レンダリング間で維持したいが画面表示に関わらない値の保持に便利だ。

出典: Useref in react theory question | Dev.to公開日:

ITニュース解説

ReactにおけるuseRefは、Reactアプリケーション開発で利用される重要なフックの一つであり、特定の値をコンポーネントの再レンダリングを伴わずに保持し続けるための仕組みを提供する。これは、useRefが変更可能なオブジェクトを返し、そのオブジェクトの.currentプロパティに値が格納されるという特性による。例えば、const myRef = useRef(null);のように宣言すると、myRefというオブジェクトが作成され、その内部にあるmyRef.currentを通じて値にアクセスしたり、更新したりできる。初期値としてnullを渡しているが、ここに任意の値を設定することが可能だ。

useRefを理解する上で、しばしばuseStateとの違いが疑問となる。useStateも値を保持するためのフックだが、両者には決定的な違いがある。useStateは、その状態が更新されると必ずコンポーネントの再レンダリングをトリガーする。これは、画面上に表示されるUI要素やその内容が変化する場合に利用され、ユーザーインターフェースとデータの同期を保つために不可欠な挙動だ。一方でuseRefは、.currentプロパティの値が変更されても、コンポーネントの再レンダリングをトリガーしない。この非同期的な特性こそが、useRefuseStateと異なる用途で使われる主な理由となる。

では、具体的にどのような場面でuseRefを使うべきなのだろうか。useRefは、値がレンダリングに影響を与えず、かつコンポーネントが再レンダリングされてもその値が持続してほしい場合に特に有用だ。例えば、タイマーのID(setIntervalsetTimeoutで取得するID)、前回の状態値、あるいはHTMLのDOM要素への直接的な参照などがこれに該当する。これらの値をuseStateで管理すると、値が変更されるたびに不要な再レンダリングが発生し、アプリケーションのパフォーマンスに悪影響を与える可能性がある。useRefを使用することで、このような内部的な値を効率的に管理し、無駄なレンダリングを防ぐことができる。

useRefの最も一般的な用途の一つは、HTMLのDOM要素へのアクセスだ。Reactは通常、仮想DOMを通じてUIを操作するが、特定の状況下では生のDOM要素に直接アクセスする必要が生じる場合がある。例えば、入力フィールドに自動的にフォーカスを当てたい場合や、メディア要素を再生・一時停止したい場合などが考えられる。このような時、useRefはDOM要素への参照を保持する「箱」として機能する。具体的には、JSX内で参照したいHTML要素にref={myRef}のようにプロパティを設定すると、その要素がレンダーされた後にmyRef.currentを通じてそのDOM要素にアクセスできるようになる。例えば、myRef.current.focus()と記述することで、特定の入力フィールドにフォーカスを合わせることが可能になる。

useRef.currentプロパティの値を更新しても、コンポーネントは再レンダリングされない。この挙動は、開発者が意図的にコンポーネントの表示を更新しないまま、内部的なデータを変更したい場合に非常に便利だ。これは、Reactのレンダリングサイクルとは独立して値を管理できることを意味する。

また、useRefと似た機能を持つcreateRefという関数も存在するが、これらにも違いがある。createRefは主にクラスコンポーネントで使用され、コンポーネントが再レンダリングされるたびに新しい参照オブジェクトが再作成されてしまう。これに対して、useRefは関数コンポーネントで使用され、コンポーネントが何度再レンダリングされても常に同じ参照オブジェクトを保持し続ける。この持続性こそが、useRefが関数コンポーネントで安定して値を管理できる理由だ。

useRefは前回の状態値を保存するためにも利用できる。これは、useEffectフックと組み合わせて実現される。useEffect内でコンポーネントの最新の状態値をuseRef.currentに手動で保存することで、次回のレンダリング時にはその前の状態値にアクセスできるようになる。例えば、ユーザーが入力した最新の値と、その一つ前の値を比較したい場合などにこのテクニックが活用される。

useRefオブジェクトは、必要であればコンポーネント間で渡すことも可能だ。しかし、子コンポーネントが親コンポーネントから受け取った参照を直接利用できるようにするためには、通常、forwardRefというReactのユーティリティ関数を用いる。forwardRefを使うことで、親コンポーネントが子コンポーネントのDOM要素や、子コンポーネント内部のuseRefで保持されている値にアクセスできるように設定できる。

useRefオブジェクトの初期値は、useRef(initialValue)のようにフックに渡す引数によって決定される。このinitialValueが、.currentプロパティの最初の値となる。何も渡さない場合やnullを渡すことも可能だ。

ReactのドキュメントでuseRefが「箱」オブジェクトと称されることがあるが、これはその機能的な役割を非常にうまく表現している。.currentプロパティは、まるで値を自由に入れ出しできる物理的な箱のようなものだ。この箱に値を入れても、取り出しても、コンポーネントの画面表示が再計算される「再レンダリング」は発生しない。つまり、UIの更新とは関係なく、内部的なデータを安全かつ永続的に保持・操作できる仕組みを提供しているため、「箱」という比喩が使われているのだ。

関連コンテンツ