📘

useRefについて

2024/08/22に公開

特徴

  1. useRefは、再レンダリングが発生しない
  2. 同期的に値を更新する

詳細

よくないケース

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