18
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【React】イベントリスナーでのステート参照方法

Last updated at Posted at 2020-12-30

目的

ボタン押下時によるステートの更新処理はたくさん記事にされている。。。
じゃあaddEventListenerを使用した際のステートの扱いについては?って思ったのでまとめてみました。

今回は画面がクリックされた際にカウントを1増やす簡単な処理を実装していきます。

addEventListenerの実装(useEffect)

実装方法自体は単純で、useEffectを使用します。
useEffectにrender後の処理、つまりaddEventListenerを記述すればOKです。

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

const Count = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // イベントリスナーを登録
    window.addEventListener("click", (event) => {
      setCount(count => count + 1);
    });
  }, []);

  return (
    <div>
      <h1>{count}</h1>
    </div>
  );
};

export default Count;

イベントリスナー内での最新のステート値の利用(useRef)

この記事のタイトルにもあるように、イベントリスナー内でセットされたステート値を使用する際は一工夫必要になります。

問題として、そのままステート値を使おうとしても更新されていない値が取得されてしまいます。
その解決方法としてuseRefを使います。

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

const Count = () => {
  const [count, setCount] = useState(0);
  const countRef = useRef(null); //  ref オブジェクト作成する
  countRef.current = count; // countを.currentプロパティへ保持する

  useEffect(() => {
    // イベントリスナーを登録
    window.addEventListener("click", (event) => {
      setCount(count => count + 1);
      console.log(count); // 更新前の値「0」が取得される
      console.log(countRef.current); // 更新後の最新のcountの値が取得される
    });
  }, []);

  return (
    <div>
      <h1>{count}</h1>
    </div>
  );
};

export default Count;

refオブジェクトの.currentプロパティにステートへの参照を保持することで、常に最新のステート値を取得することが出来るようになります。

まとめ

公式にもあるように、useRef は何もDOM への参照を保持するためだけにあるのではありません。その current プロパティの値は書き換え可能かつどのような値でも保持することができます。
https://ja.reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables

18
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?