ReactのuseRefフックについて
useRefは、ReactでDOM要素やミュータブルな値を保持するためのフックです。このフックを使用することで、再レンダリングを発生させずにデータを参照・更新することが可能になります。例えば、DOMに直接アクセスしたり、以前の状態を保持する場合に便利です。
概要
以下に、useRefを使ってDOM要素にアクセスする例を示します。この例では、ボタンをクリックするたびに入力フィールドにフォーカスを当てます。
import React, { useRef } from "react"const App = () => {const inputRef = useRef(null)const focusInput = () => {// inputRef.currentに格納されているDOM要素にフォーカスを当てるinputRef.current.focus()}return (<><input ref={inputRef} type="text" /><button onClick={focusInput}>Focus Input</button></>)}export default App
このコードでは、useRefを使って入力フィールドへの参照を取得し、ボタンをクリックするたびにそのフィールドにフォーカスを当てています。
useRefとは?
useRefは、再レンダリングを引き起こさない参照を保持するためのフックです。通常、Reactの状態やプロパティの変更はコンポーネントの再レンダリングを引き起こしますが、useRefはこのルールに従いません。そのため、useRefを使って保持している値が更新されても、コンポーネントは再レンダリングされません。
useRefの構文
const refContainer = useRef(initialValue)
initialValue: 参照の初期値を設定します。useRefは初回レンダリング時にのみこの値を設定し、それ以降は変更されません。refContainer:currentプロパティを持つオブジェクトが返されます。このcurrentに参照したい値やDOM要素を格納します。
DOMへの直接アクセス
Reactでは、通常、仮想DOMを通じてDOMを操作しますが、useRefを使うと特定のDOM要素に直接アクセスできます。これは、フォーム要素へのフォーカスやメディアの再生制御など、特定の状況で必要になる場合があります。
const inputRef = useRef(null)useEffect(() => {inputRef.current.focus() // 初回レンダリング後に自動的にフォーカスを当てる}, [])
上記の例では、コンポーネントがマウントされた直後に入力フィールドにフォーカスを当てています。
ミュータブルな値の保持
useRefはDOM要素だけでなく、任意のミュータブルな値を保持するためにも使えます。この場合、useRefで保持した値が更新されても、再レンダリングは発生しません。
const renderCount = useRef(0)useEffect(() => {renderCount.current += 1console.log(`レンダリング回数: ${renderCount.current}`)})
この例では、renderCountを使ってコンポーネントがレンダリングされた回数を数えています。renderCount.currentの値が更新されても、コンポーネント自体は再レンダリングされません。
状態の保持と比較
useRefとuseStateの違いは、useRefは再レンダリングをトリガーしない点です。そのため、再レンダリングが不要な一時的なデータを保持する場合に適しています。逆に、UIに影響を与えるデータを保持する場合は、useStateを使用するのが一般的です。
const prevCountRef = useRef()useEffect(() => {prevCountRef.current = count}, [count])const prevCount = prevCountRef.current
上記の例では、countの前回の値を保持し、現在のcountと比較することができます。
useRefの注意点
- 再レンダリングを発生させない:
useRefは、保持している値が更新されても再レンダリングを発生させないため、UIに反映させたい値には適していません。 - 参照の初期化に注意:
useRefの初期値はnullやundefinedであることが多いため、実際に使用する際にはcurrentが意図した値を持っているか確認する必要があります。
const inputRef = useRef(null)const handleClick = () => {if (inputRef.current) {inputRef.current.focus()}}
このように、currentがnullでないことを確認してから使用することで、エラーを防ぐことができます。
まとめ
useRefフックは、DOM要素やミュータブルな値を管理するための便利なツールです。再レンダリングを発生させずに参照を保持できるため、特定の場面でパフォーマンスを最適化するのに役立ちます。また、useRefを適切に使用することで、状態管理と参照管理を効率的に行うことが可能になります。