レンダーの純粋性を壊さずに、useRef で DOM を操作し、インスタンスの値を保持します。
このレッスンを Kodokon で開くuseRef は変更可能な箱 - current という単一のプロパティを持つオブジェクト - を返し、その識別子はあらゆるレンダーを生き延びます。state との根本的な違いが 2 つあります。ref.current の変更は 再レンダーを引き起こさず、変更は次のレンダーを待たずに即座に見えます。そこから 2 つの用途の系統が生まれます。DOM ノードを参照すること、そして表示を駆動せずにレンダーをまたいで生き残らなければならないインスタンスの値を格納することです。
import { useEffect, useRef } from "react";
function SearchField() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} type="search" />;
}インスタンスの値の側では、レンダーを引き起こさずに保持しなければならないものはすべて ref に属します。setInterval が返す id、外部ライブラリのインスタンス(地図、エディター、動画プレーヤー)、前回のレンダーの値などです。黄金律は変わりません。レンダーは props と state の純粋関数でなければなりません。ref はエフェクトやイベントハンドラーの中で読み書きするものであり、レンダー中ではありません。
import { useEffect, useRef } from "react";
function usePrevious(value) {
const ref = useRef(undefined);
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}自分のコンポーネントから DOM ノードを公開するには、ref を渡していきます。React 19 以降、ref は関数コンポーネントのごく普通の prop です。それ以前は forwardRef を通すことが必須でした。最後に身につけたい反射がひとつ。結果を記述するのに state で足りるなら(CSS クラス、disabled 属性)、宣言的なアプローチを優先しましょう。ref は React が扱わない領域のために取っておきます。フォーカス、テキスト選択、要素の測定、スクロール、メディア再生などです。
import { useRef } from "react";
function TextField({ ref, ...props }) {
return <input ref={ref} {...props} />;
}
function Form() {
const fieldRef = useRef(null);
return (
<>
<TextField ref={fieldRef} />
<button onClick={() => fieldRef.current.focus()}>
Give focus
</button>
</>
);
}