【React】でDOMを直接操作するuseRefの使い方とrefとstateの違い
ReactでDOMを直接操作するuseRefの使い方を紹介します。
useRefの使いどころ
useRefをいつ使うかですが、DOMのメソッドを使いたいときです。
たとえば、よくあるユースケースとしては、input要素にフォーカスを当てたいときやblur()でフォーカスを取り除きたいときなど、DOM要素のメソッドはプロパティを使いたいときに使用します。
あとは、動画の再生、停止をボタンクリックで操作したいときにも、videoタグのpauseイベントで停止、playイベントで再生という操作をする必要があるので、useRefを使用します。
ReactでDOMを直接操作するuseRefの使い方
ref属性でuseRefの変数を渡すと、currentというプロパティがあり、currentプロパティに対して値を保持できる仕組みになっています。
useRefは、再レンダリングを発生させずに、値を保持する方法です。
stateでは、再レンダリングが発生するのでコンポーネントに保持している値は破棄されてしまいますが、
useRefを使うと、たとえ再レンダリングしてもcurrenctプロパティに値を保持したままにすることが可能です。
useRefを変数に格納すると、refオブジェクトを返します。
そのオブジェクトには、currentプロパティがあり、そこに値を設定します。
ref.currentで値にアクセスすることができます。
その値は読み書きどちらもすることが可能です。
refとstateの違い
再レンダリング後に値が保持できるかどうか
refは、再レンダリングされても情報が保持できます。
stateでは、レンダリングされると初期化されます。
値変更に伴って再レンダリングが発生するかどうか
refの値を変更しても再レンダリングが発生しません。
stateは変更されると、再レンダリングが発生します。
DOMを直接操作するかどうか
refオブジェクトをJSXのref属性にわたすと、そのDOMにアクセスできるようになります。
注意点としては、refの値を変更しても再レンダリングが発生しないという点で、
refの値自体は変更されていても、再レンダリングが発生しないため、コンポーネントが更新されず、画面の表示上の見た目も変化しない点です。
値は変わっても見た目が変わらないので注意が必要です。
useRefの例
import { useState, useRef } from "react";
const FocusInput = () => {
const [value, setValue] = useState("");
const inputRef = useRef();
return (
<div>
<h3>離れた要素を直接操作</h3>
<input type="text" ref={inputRef} value={value} onChange={(e) => setValue(e.target.value)} />
<p>適当なDOM</p>
<button onClick={() => inputRef.current.focus()}>
フォーカス
</button>
</div>
);
};
const Sample = () => {
return (
<>
<FocusInput />
</>
);
};
export default Sample;
インポート
import { useState, useRef } from "react";
まずは、reactからuseRefをインポートします。
変数を作成
const inputRef = useRef();
そして、useRefを変数に持ちます。
ref属性にセット
<input type="text" ref={inputRef} value={value} onChange={(e) => setValue(e.target.value)} />
そして、ref属性にその変数を渡します。
JSXで使う
<button onClick={() => inputRef.current.focus()}>
フォーカス
</button>
そうすることで、ref属性に指定したDOM要素のメソッドなどを使用することができるようになります。
上の場合だと、currentというプロパティがあり、そこにinputが指定できているので、inputのプロパティなどにアクセスすることができます。
currentを経由して、focus()メソッドを使用することができます。