useRefとは?
まずは、useRefについて簡単に説明します。
useRefはReactの状態管理をするhook(フック)の1つです。
hookは、他にもuseStateやuseEffectなど、様々なものがあります。
useRefは、DOM要素へのアクセスや、コンポーネント内で保持したい値を扱うために使用されます。
コンポーネントが再レンダリングされても値が保持される特徴があります。
この特徴に注目して、以下のサンプルコードを見てみてください。
import React, { useEffect, useRef, useState } from 'react';
import './App.css';
function App(): JSX.Element {
const previousValueRef = useRef<string>('');
const [currentValue, setCurrentValue] = useState<string>('');
const handleInputChange = (event: any) => {
// 現在の値を保持
previousValueRef.current = currentValue;
// 入力された最新の値を取得
setCurrentValue(event.target.value);
};
return (
<div>
<input type="text" value={currentValue} onChange={handleInputChange} />
<p>前回の値: {previousValueRef.current}</p>
<p>現在の値: {currentValue}</p>
</div>
);
}
export default App;
useRefの使い道
では、本題に入っていきます。
useRefが何かについては把握したけど、
どういうタイミングで使用するかのイメージは湧きづらいと思います。
今回は、このuseRefを使って実現できることを紹介していきます。
特定の要素にフォーカス
まず1つ目は、特定の要素にフォーカスしたい際にuseRefを使用することができます。
複数のテキストボックスが存在する中で特定の要素にフォーカスするコードを紹介します。
import React, { useRef, useEffect } from 'react';
function App(): JSX.Element {
const inputRef = useRef<HTMLInputElement>(null);
// 初回レンダリング時
useEffect(() => {
if (inputRef.current) {
// input要素にフォーカスを設定
inputRef.current.focus();
}
}, []);
return (
<div>
<input type='text' />
<input type="text" />
{/* 3つ目の要素にフォーカス */}
<input type="text" ref={inputRef} />
</div>
);
}
export default App;
このように、ページの読み込み時に毎回特定の要素にフォーカスすることができます。
useRefでは、レンダリングされたDOM要素への参照を保持するのに便利です。
Submit前に何らかの処理をする
次は、Form(フォーム)の送信前にuseRefを使用して、制御をしてみます。
useRefはDOMやコンポーネントへの参照を取得することが可能なので、
比較的容易に制御をすることが可能になります。
import React, { useRef, useState } from 'react';
function App(): JSX.Element {
const inputRef = useRef<HTMLInputElement>(null);
const handleSubmit = (event: any) => {
// イベントの制御
event.preventDefault();
// 値の保持
if (inputRef.current) {
// アラートに値を表示
// 値を使用してForm送信前に何らかの処理をする
alert(`Input Value: ${inputRef.current.value}`);
// Formの送信
inputRef.current.form?.submit();
}
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
<button type="submit">Submit</button>
</form>
);
}
export default App;
アニメーションの制御
次は、少し面白いです。
useRefで、ボックス要素に参照を保持し、useStateでアニメーションの管理をしています。
import React, { useRef, useState } from 'react';
function App(): JSX.Element {
const boxRef = useRef<HTMLDivElement | null>(null);
const [expanded, setExpanded] = useState<boolean>(false);
const toggleBox = (): void => {
if (boxRef.current) {
const newWidth = expanded ? '100px' : '200px';
const newColor = expanded ? 'blue' : 'red';
boxRef.current.style.width = newWidth;
boxRef.current.style.backgroundColor = newColor;
setExpanded(!expanded);
}
};
return (
<div>
<div
ref={boxRef}
style={{
width: '100px',
height: '100px',
backgroundColor: 'blue',
transition: 'width 0.5s ease',
}}
onClick={toggleBox}
/>
</div>
);
}
export default App;
最後に
useRefの使い道は意外と多く、手の届かない痒いとこに手が届くようになった感じ(?)がしますね!
今回紹介した例以外にも様々な使い道があるので、色々見つけてみると面白いと思います。
コメント