React、イベントリスナ内で使うuseStateの更新

先日Reactを使用しているときに困ったことが発生しました。
イベントリスナ内で取得したいstateの値をsetterで値を更新しても反映がされませんでした。

stateが更新されない理由

stateが更新されない理由として、setterで値を更新した際は即座に更新されるわけではなく関数が呼び出された後に行われることは知っていました。
しかし、今回のパターンはクリックイベントリスナ内で使用しているstateをボタンでtrue/falseで更新をしていました。

これならば、上記で記載したsetterで更新した直後にstateを使用しているケースには当てはまらないため更新されないのは何故か・・・。結論としては、イベントリスナで登録したときのstateの状態を保持し続けることが原因でした。

では、どのようにこの問題を解決するか・・・useRefで最新の状態を取得して対応をしようと考えました。
useRefはDOMにアクセスする手段として利用されるシーンが多いと思います。

サンプル

TypeScript
const [isAddMode, setIsAddMode] = useState<boolean>(false);
const isAddModeRef = useRef(false); //  ref オブジェクト作成
isAddModeRef.current = isAddMode; // isAddModeを.currentプロパティへ保持

useEffect(() => {
 ...
  map.on("click", (e) => {
    if (isAddModeRef.current === false) return;
  ...
  });
 ...
}

所感

.currentプロパティの値は書き換え可能かつどのような値でも保持することができるため、基本的にはuseRef を使用したコードは避けるべきではあると思います
そのため、別の解決方法が見つかれば記事にしていきたいと思います。

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA