プログラミング初心者のための入門ブログエンジニアが未来を切り開く。useRefフックの型指定と使い方この広告は、90日以上更新していないブログに表示しています。入門useRefフックを使用してrefを宣言するさまざまな方法が、現在のrefプロパティの不変性にどのような影響を与えるかを学びます。当記事では、currentプロパティを不変にする方法、可変にする方法を紹介します。Reactでは、レンダリングに使用するデータは不変です。状態の一部の変更は、セッターまたはレデューサーを通じて反映されます。);};これらの変更では、エフェクトの実行、メモ化の無効化、およびコンポーネントの再レンダリングのために観察が可能です。useRefでは、コンポーネントまたはフックの実行全体で変更可能な変数を初期化し、アクセスできるようにします。レンダリングのたびに、useRefは1つの引数を取りデータを格納できる同じRefオブジェクトを返すので、可変となります。変更可能なrefオブジェクトを返します。』という名前のプロパティを含んでいます。初期値は、useRefに渡された引数の値です。引数が存在しない場合、currentプロパティはundefinedに設定されます。ref.current++}/>;これは、書き換え可能な値をcurrentプロパティ内に保持することができる変数のようなものです。下記では、初期値をnullで含めております。useRef<number>(null);//読み取り専用useRefフックを作成するときは、デフォルト値としてnullを渡すことも重要です。通常refはnullで初期化します、これは後でJSX呼び出しで設定するためです。useRefフックの初期値をnullにした場合、戻り値のrefオブジェクトは読み取り専用になりますその場合は書き換える事はできません。Reactコンポーネントへの参照を格納する場合、開発者は通常、初期値をnullに設定します。フックを初期化するとオブジェクトが返され、そのオブジェクトにはcurrentというプロパティが含まれています。フックに使用した初期値がそのプロパティの値となります。useRefフックの最も一般的な用途は次の2つとなります。DOM要素への直接アクセスcurrentの可変性と不変性は実行時ではなく、型レベルで適用されます。変数の値を保持するのは、useStateフックと少し似ておりますが重要な違いがあります。それを明確にしましょう。useStateとuseRefの違いuseStateとの主な違いは次のとおりです。状態を更新すると、コンポーネントが再レンダリングされます。refに格納されている値を更新しても、何も起こりません。useStateは2つのプロパティまたは配列を返します。値または状態で、もう1つは状態を更新する関数です、対照的にuseRefは格納された実際のデータである1つの値のみを返します。useStateでは、状態またはその値を更新するためにコンポーネントを再度レンダリングする必要があります。refに格納されたデータまたは値は、コンポーネントの再レンダリング後でも同じままです。したがって、参照はコンポーネントのレンダリングに影響しませんが、状態には影響します。参照値が変更されると、更新または再レンダリングする必要なく更新されます。これは、バグではありません機能です。useRefフックには、DOM要素へのアクセスと変数に値を保持する用途がありますが、どちらの用途にも異なる型が必要となります。単純なものから始めて、useRefフックが役立つユースケースを見てみましょう。useRefでDOMノードの入力方法useRefフックの不変currentは通常、DOM要素で使用されます。DOM要素の参照では、次のような便利な事ができます。HTML要素には独自の型定義がございます。useRef<HTMLInputElement>(null);一般的なユースケースは、要素の参照を取得しボタンがクリックされるたびにその要素にフォーカスすることです。下記のアプローチは、単純に見えるかもしれませんが型や関数コンポーネントに慣れていない人にとっては難しいと感じるかもしれません。CodePen.名前とメールの情報を受け取るための2つのテキスト入力があり、また2つのボタンがあります。何もしていないときは、useEffectフックを使用し最初のテキスト入力がフォーカスされます。ボタンがクリックされると、そのボタンに対応するテキスト入力にフォーカスが当たります。デモで確認すると、より直感的に理解できるかと思います。先述した通り、TypeScriptにはDOM要素の型が組み込まれており、それを利用することができます。null>(null);入力の場合、型の名前はHTMLInputElementとなります。?を付けていることに注意してください。これは、TypeScriptではnameRef.currentがnullになる可能性があるためです。上記では、最初の実行前にReactによって入力されるため、nullにならないことがわかっています。?を追加することは、TypeScriptがその問題について満足するための最も簡単な方法となります。参照の代わりに値を格納するために使用することです。refのcurrentプロパティを変更可能にするには、ref自体の宣言方法を変更する必要があります。基本的にはuseStateフックと同じですが、useRefに値を保持させたいので、その型を指定します。下記のように、refはすべてのクリック参照を追跡可能です。カウントの追跡となります。CodePen.refは、Reactの再レンダリングメカニズムを使用せずに何らかの状態を追跡する必要があるときはいつでも、Reactの関数コンポーネントのインスタンス変数として使用できます。refをインスタンス変数として使用して値を取得し、イベントと引数を並列に渡しております。値を状態または変数として格納する代わりに参照が使用されます。以前の状態を追跡し参照を保持することです。インクリメントまたはデクリメントするたびに、ref内にcountの値を格納が可能です。他の例として、タイマーを扱うコンポーネントとしてもuseRefフックは、タイマーへの参照を保持するための理想的な候補となっています。CodePen.下記のようにuseRefが提供された型に属する値で初期化される場合、refのcurrentプロパティは不変から変更可能、つまり可変にする事ができます。null>(null);useRefフックをnullで初期化し、実際の型に基づいてユニオン型を使用し、型引数にnullを使用する必要があります。refは、状態が変化しても影響を受けない状態のオブジェクトに基づいて定義できる変数です。何か他のことをするように指示するまで、その値を保持します。下記のようにしても同じ事ができます。CodePen.この場合では、useRefフックの初期値をnullにした場合、戻り値のrefオブジェクトは読み取り専用になるため、エラーをスローします。0;として代入する事でtimerRefを参照し保持可能にする事が可能です。};startHandler()関数は、Startボタンが押されたときに呼び出されます。呼び出された後にタイマーを開始し、timerRefを参照し保存します。ストップウォッチを停止するには、Stopボタンをクリックします。stopHandler()関数は、参照からtimerRefにアクセスし、タイマーを停止します。ストップウォッチがアクティブな状態でコンポーネントがアンマウントされると、useEffect()のクリーンアップ関数がタイマーを停止させることになります。最後にReactとTypeScriptを使い始めたとき、変更可能な参照と不変の参照の違いが非常にわかりにくいと思います。結局のところuseRefは要素のref属性を利用してHTML要素として使われるのか、Reactの再レンダリングを引き起こさない状態を追跡するためのインスタンス変数として使われるかのどちらかです。コンポーネントの再レンダリングの間、参照の値は永続的です。参照の更新は、状態の更新とは対照的にコンポーネントの再レンダリングをトリガーしません。参照はDOM要素にもアクセス可能ですが、TypeScriptにはDOM要素の独自の型が組み込まれています。本日は以上となります。最後まで読んで頂きありがとうございます。当記事がお役に立ち、いくつかの疑問が解消されたことを願っております。17:56ご訪問いただきありがとうございます。私はdeve.Kと申します。現役のReact.jsプログラマーでありWebアプリ開発に携わっています。当ブログでは、ITやプログラミングの学習を目的としたブログを運営しています。専門分野はJS/TS/Node.js/React/Next.jsです。質問や相談、または学びたい分野のリクエストなどがありましたら、お気軽にお問い合わせください。このブログでは、ITやプログラミングに関する情報を分かりやすく、かつ実践的な内容でお届けしています。皆様にとって有益な情報を提供し、より良い学習体験を得ていただけるよう、精一杯の努力をしてまいります。今後ともどうぞよろしくお願いいたします。[deve.K].はてなブログをはじめよう!dev04Kさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。