【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()メソッドを使用することができます。