🚀

最新のReact hooksに追いつく useRef編

に公開

最新のReact hooksに置いていかれたフロントエンドエンジニアが最新のhooksに追いつくためのブログです。2回目useRefについてです(9割書き上げていたのにすべて消えていた。。。)

useRefとは

useRefは、一言でいうと値などを保持するための箱のようなものです。「それなら、useStateでいいやん!」と思ったそこのあなた、私もそう思ってました。ですがuseStateでは不可能なことをuseRefは実現してくれます。
ただし、値を更新しても再レンダーが走らないという特徴です!

「レンダーをさせずに値を覚えておきたい」「DOMを直接操作したい」
そんなときに使えるのがuseRefです!

useRefの書き方

useRefの書き方は基本的にはuseStateと一緒です。

import { useRef } from "react";

const inputRef = useRef<HTMLInputElement>(null);

useRefを使うと、{ current: 初期値 }というオブジェクトが返ってきます。
このcurrentプロパティにアクセスすることで、値の読み書きができます。

useRefの使いどころ

useRefは使い方を実際に見てみないと腑に落ちないと思いますので、例を挙げてみていきましょう!
ここでuseStateの違いが理解できるようになるはずです。

1, DOM要素の直接操作したいとき

useRefの代表的な使い方がこれです。
最初にuseRefは値などを入れる箱といいましたが、DOM要素を入れることができます。
たとえば、ボタンを押したときにテキストボックスへフォーカスを当てたい場合などに使います。

import { useRef } from "react";

export default function InputFocus() {
  const inputRef = useRef<HTMLInputElement>(null);

  const handleClick = () => {
    // DOM要素に直接アクセスできる
    inputRef.current?.focus();
  };

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={handleClick}>フォーカス!</button>
    </div>
  );
}

ref={inputRef} と書くことで、そのDOM要素(ここでは<input>)が
inputRef.currentに代入されます。

つまり、inputRef.currentには実際の HTML要素(HTMLInputElement) 入っているということです。

2, 値を保持したいが、再レンダーさせたくないとき

この使い方がuseStateと最大の違いが発揮される部分です。
useStateを使うと、値を更新した際に再レンダーが走ります。
一方で、useRefは再レンダーされません。
前回の値を保持して比較したい場合などに便利です。

import { useState, useRef, useEffect } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);
  const prevCount = useRef(0);

  useEffect(() => {
    prevCount.current = count;
  }, [count]);

  return (
    <div>
      <p>今の値: {count}</p>
      <p>前の値: {prevCount.current}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

useRefのありがたみが何となくわかったでしょうか笑

  • 画面に出したい値 → useState
  • 画面には出さないけど覚えておきたい値 → useRef
    こんな感じで覚えてもらえるといいと思います!
    useStateとの違いをしっかり理解したうえで使い分けられると無駄なレンダー処理が入らずにパフォーマンス向上にも繋がります!
    ただし、画面上の値を更新したい場合はuseStateを使うようにしましょう!

まとめ

今回はuseRefに関してまとめてみました。
refの概念もクラスコンポーネント時代に使う場面は多かったので個人的には、理解しやすかったですね
次はuseMemo編でお会いしましょう

Discussion