[React.js] - パート12: React Hooks - useRef Hook

Ace Lennox
ReactのuseRef
フックは、レンダリング間で値を保持したり、DOM要素に直接アクセスしたり、再レンダリングを引き起こさずに変更可能な値を管理したりするための多用途なツールです。このガイドでは、実際的で創造的な例を通じてuseRef
の使い方を詳しく解説します。
useRef
とは?
useRef
フックは、コンポーネントが再レンダリングされても値を保持する方法を提供します。useState
と異なり、useRef
を更新してもコンポーネントは再レンダリングされません。また、DOM要素に直接アクセスする場合にも役立ちます。
useRef
の主な特徴
再レンダリングを引き起こさない: 値を更新してもレンダリングサイクルには影響しません。
DOM要素への直接アクセス: 必要に応じてReactの抽象化をバイパスできます。
以前の状態を保持: レンダリング間で状態値を記録できます。
例を通じて学ぶuseRef
例1: レンダリング回数を追跡
コンポーネントのレンダリング回数を追跡しつつ、無限ループを避ける例です:
import { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom/client";
function RenderCounter() {
const [text, setText] = useState("");
const renderCount = useRef(0);
useEffect(() => {
renderCount.current += 1;
});
return (
<>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<h2>このコンポーネントは{renderCount.current}回レンダリングされました!</h2>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<RenderCounter />);
useRef
を使用することで、レンダリング回数を追跡しても追加の再レンダリングを引き起こしません。入力フィールドにテキストを入力して、カウントが動的に増加する様子を確認してください。
例2: 入力フィールドにフォーカスを設定
useRef
を使うと、ボタンをクリックしたときに入力フィールドに直接フォーカスを設定できます:
import { useRef } from "react";
import ReactDOM from "react-dom/client";
function InputFocus() {
const inputRef = useRef();
const handleFocus = () => {
inputRef.current.focus();
};
return (
<>
<input type="text" ref={inputRef} placeholder="ボタンをクリックしてフォーカスを当てる" />
<button onClick={handleFocus}>フォーカスを設定</button>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<InputFocus />);
この例では、useRef
を使用してDOM操作を行いながら、Reactの宣言的な性質を保っています。
例3: 前回の値を記憶
useRef
を利用して、状態の前回の値を記録します:
import { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom/client";
function RememberPrevious() {
const [current, setCurrent] = useState("");
const previous = useRef("");
useEffect(() => {
previous.current = current;
}, [current]);
return (
<>
<input
type="text"
value={current}
onChange={(e) => setCurrent(e.target.value)}
/>
<h2>現在の値: {current}</h2>
<h2>前回の値: {previous.current}</h2>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<RememberPrevious />);
この例では、useState
、useEffect
、useRef
を組み合わせて、前回の状態を効率的に追跡しています。
例4: 要素の寸法を測定
次に、useRef
を使って要素の寸法を取得する例です:
import { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom/client";
function MeasureBox() {
const boxRef = useRef();
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
useEffect(() => {
const { offsetWidth, offsetHeight } = boxRef.current;
setDimensions({ width: offsetWidth, height: offsetHeight });
}, []);
return (
<>
<div
ref={boxRef}
style={{ width: "200px", height: "100px", background: "lightblue" }}
></div>
<h2>幅: {dimensions.width}px</h2>
<h2>高さ: {dimensions.height}px</h2>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<MeasureBox />);
この例では、useRef
を使用してDOM要素にアクセスし、その寸法を取得しています。
useRef
のベストプラクティス
必要な場合にのみ使用: DOM操作や値の永続化が必要な場合に限定して使用します。通常の状態管理には
useState
を優先しましょう。状態の代替として使わない: UIの再レンダリングが必要な場合は
useState
を使用してください。.current
を確実に確認:.current
プロパティが利用可能であることを確認してからアクセスします。
まとめ
useRef
フックは、値の永続化、DOM操作、状態の追跡を可能にする強力なツールです。このガイドで紹介した例を試して、useRef
の持つ柔軟性と可能性を体感してください。
プロジェクトにuseRef
を取り入れることで、Reactアプリのワークフローがさらにシンプルになります!
ソースコード
このプロジェクトの完全なソースコードはGitHubで利用可能です。