windowにクリックイベントを登録して、クリックしたときにstateの状態によって処理を切り分けたいので、こう書いてみた。
import { useState, useEffect, useMemo } from "react"; export default function App() { const [id, setId] = useState(""); const handler = () => { console.log("id", id); if (id === "1") { console.log("OK"); } else { console.log("NG"); } }; useEffect(() => { window.addEventListener("click", handler); return () => { window.removeEventListener("click", handler); }; }, []); console.log("State id", id); return ( <div> <button onClick={() => { setId("0"); }} > Set 0 </button> <button onClick={() => { setId("1"); }} > Set 1 </button> </div> ); }
ボタンを押すとstateの状態が変わって再レンダリングされるのに、リスナに設定した関数の中は以前のstateの値を持ったままになってしまう。
イベントの登録をするuseEffectに依存配列としてstateの値を設定して、stateが変わったときにイベントを登録しなおせば、期待通りの動作になった。
useEffect(() => { window.addEventListener("click", handler); return () => { window.removeEventListener("click", handler); }; }, [id]);