【React.js】React の ref、useRef、forwardRefについて改めてまとめてみた!

  • 2023年5月2日
  • 2023年5月14日
  • React.js

こんにちは。

野中やすおです。

今回の記事では、React.jsが提供する機能であるrefについて勉強がてらまとめています。

refとは何か

refとはrenderメソッドで作成されたDOMノードもしくはReact要素の参照を保持するオブジェクトのことです。refオブジェクトは、次に紹介するuseRefによって具体的に生成されます。

useRefとは何か

useRefは、React Hooks(フック)1つで、refオブジェクトを生成し再レンダリングを発生させずに値を保持する方法です。再レンダリングを発生しないという点がuseStateと異なる点です。

useRefを使った例

useRefを使った具体例を紹介します。以下のコードは、公式サイトでも例示されている「テキスト入力のフォーカス」機能です。

ref.currentプロパティを使用することで、参照した現在の値にアクセスすることができます。

またinputRef.current.focus()をconsole.log(inputRef)に置き換えることで「インプット要素をフォーカス」 ボタン押下時にコンソールに{current:input}というのが表示されるようになります。

参照した値を保持できることから、とてもuseStateの機能に似ていますがあくまで再レンダリングはしません。公式の以下のページにuseRefとuseStateの違いについてまとめられているので、こちらも参考になります。

The library for web and native user interfaces…

一方で公式サイトでも

Don’t read or write ref.current during rendering. If some information is needed during rendering, use state instead.

とあるようにレンダリング中にref.currentを使用してはいけません。レンダリング中に何をしたい場合には、useStateの方を使うようにします。

forwardRefとは何か

forwardRefは、コンポーネント内のDOMにRefオブジェクトを渡すための機能になります。つまり、子コンポーネント内の DOM に直接アクセスしたいときに使用されます。

というのもrefは、親コンポーネントから子コンポーネントへprops形式で渡して参照することができないため、 参照したい場合は、子コンポーネント内でfowardRefを使用する必要があります。

またforwardRefとuseImperativeHandleを一緒に使用することで、親コンポーネントから受け取ったrefオブジェクトをカスタマイズできるようになります。

forwardRefを使った例

forwardRefを使った具体例も紹介します。こちらのコードも公式サイトでも例示されている「テキスト入力のフォーカス」機能を例にしました。

useImperativeHandleは、公式サイトでもあるように、第1引数に「親コンポーネントから受け取ったrefオブジェクト」、第2引数に「オブジェクトを返す関数」を設定します。

The library for web and native user interfaces…

 

最後にrefは、あくまで特別に使用する場合にのみ使われるものであって(escape hatch)、頻繁に使用されるものではありません。その点を注意しつつ、Refを便利に使っていきましょう!