📘
useRefについて
特徴
- useRefは、再レンダリングが発生しない
- 同期的に値を更新する
詳細
よくないケース
useRef()は、current:initialValueを作成して、そのinitialValueをcurrentが参照しているという意味。
const Count = () => {
const count = useRef(0);
const [countUp, setCountUp] = useState(0);
const RefInclement = () => {
count.current! += 1;
console.log(count.current);
};
const stateCunt = () => {
setCountUp((prev) => prev + 1);
console.log(countUp);
};
return (
<div>
<p>{count.current}</p>
<p>{countUp}</p>
<button onClick={RefInclement}>+</button>
<button onClick={stateCunt}>+</button>
</div>
);
};
上記の場合、useRefのcurrentプロパティはuseRef(0)の0を参照しており、この値を+ボタンを押すと足していくというコードで、この場合、useRefは再レンダリングが発生しないので値が画面上に更新されない。consoleでは、即座に足されている。
こういった再レンダリングが必要な処理には向かない。
使えるケース
const handleSubmit = (event: React.FormEvent) => {
event?.preventDefault();
};
const inputValue = useRef<HTMLInputElement | null>(null);
const handleValue = () => {
const value = inputValue.current?.value;
// currentは、refで指定しているDOM要素を意味している。refがない場合は、useRef(0)の0がcurrentを指す。
// 再レンダリングが発生しないかつ、同機的に更新される。
console.log(value);
};
return (
<div className="flex justify-center items-center h-screen bg-green-100">
<form
className="w-full max-w-md bg-white p-8 rounded-lg shadow-lg"
onSubmit={handleSubmit}
>
<h2 className="text-2xl font-bold mb-6 text-gray-800 text-center">
テストフォーム
</h2>
<div className="mb-4">
<label
className="block text-gray-700 text-sm font-bold mb-2"
htmlFor="username"
>
名前
</label>
<input
ref={inputValue}
id="username"
type="text"
className="w-full p-3 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-green-500"
placeholder="Enter your username"
/>
</div>
<button
onClick={handleValue}
type="button"
className="w-full bg-green-500 text-white p-3 rounded hover:bg-green-600 transition duration-300"
>
テスト登録
</button>
</form>
</div>
input属性ref={inputValue}を指定して、useRefを使用する。この場合、ref={}で指定した部分がcurrentになる。つまり、inputValue.currentはinput要素丸ごと、参照しており,input.current.valueを使用するとinput要素に入力された値を参照することになる。今回はその値をvalueに格納して、console.logで表示している。こういった処理の場合は、サイレンダリングが走らないので効率的に値を参照できる。
Discussion