React 中的上下文值未在事件侦听器内更新

Vis*_*har 1 reactjs react-context react-hooks

我正在用 React 构建一个简单的游戏。问题是上下文已正确更新,但事件侦听器函数内的上下文值未更新。如果我访问事件函数外部的值,则会呈现新的更新值。

对于第一个 keyup 事件,该值将为 0,但对于下一个事件,它应该是新的更新值。

  const updateGame = useUpdateGame();
  const gameData = useGameData(); 
  //Assume Default gameData.board value is 0

  // Assume context value updated to 5

  useEffect(() => {
    document.addEventListener("keyup", (e) => {
      e.stopImmediatePropagation();
      console.log(gameData.board) //0
      handleKeyPress(e.key, gameData.board, updateGame);
    });
  }, []);
  console.log(gameData.board) //5
Run Code Online (Sandbox Code Playgroud)

Tus*_*ahi 5

事件侦听器已关闭上下文的旧值(认为是闭包)。您需要将上下文的更新值保留在事件侦听器中。

这可以通过每次上下文值更改时定义事件侦听器或使用ref.

  1. 每次渲染发生变化后,在 useEffect 中注册并清除事件监听器gameData
const updateGame = useUpdateGame();
  const gameData = useGameData(); 

  useEffect(() => {
    let listener = (e) => {
      e.stopImmediatePropagation();
      handleKeyPress(e.key, gameData.board, updateGame);
    };

    document.addEventListener("keyup", listener);

return () => {
    document.removeEventListener("keyup", listener);
};
  }, [gameData]); //updateGame should be added here too ideally
Run Code Online (Sandbox Code Playgroud)
  1. 保留一个模仿您正在寻找的值的参考。ref是稳定的容器,因此它们始终具有正确的状态值
  const updateGame = useUpdateGame();
  const gameData = useGameData(); 
  const gameDataRef = useRef(gameData?.board ?? null);


  useEffect(() => {
    document.addEventListener("keyup", (e) => {
      e.stopImmediatePropagation();
      handleKeyPress(e.key, gameDataRef.current, updateGame);
    });
  }, []);

  useEffect(() =>{
   gameDataRef.current = gameData.board;
  },[gameData]);
Run Code Online (Sandbox Code Playgroud)