【问题标题】:Why is React using the wrong value in useState?为什么 React 在 useState 中使用了错误的值?
【发布时间】:2020-10-23 06:23:49
【问题描述】:

我有一个像这样的 React 组件:

https://codepen.io/darajava/pen/NWrdWeP?editors=0010

function TestUseState() {
  const [count, setCount] = useState(0);
  const buttonRef = useRef(null);

  useEffect(() => {
    buttonRef.current.addEventListener("click", () => {
      alert(count);
    });

    setCount(10000);
  }, []);
  
  return (
    <div ref={buttonRef}>
      Click
    </div>
  )
}

我在按钮上设置了一个事件监听器,它似乎取状态的初始值,之后直接设置它。这是预期的行为吗?我怎样才能避免这种情况?

有问题的实际代码(无效,仅添加了相关部分):

const Game = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [player, setPlayer] = useState<IPlayer>();

  const setPosition = (newPos) => {
    console.log(player); // <--- player is undefined on mousemove
  };

  useEffect(() => {
    canvas = canvasRef.current;
    ctx = canvas.getContext('2d');
    
    canvas.addEventListener('mousemove', (e: MouseEvent) => {
      setPosition(getCursorPosition(canvas, e));
    });
  }, []);


  return (
    <canvas ref={canvasRef} styleName="canvas" />
  );
}

【问题讨论】:

  • 您已经关闭了初始count 状态进入点击回调。只需使用可以附加到元素的普通 onClick 处理程序。
  • 谢谢德鲁,但这是我实际尝试做的一个非常简化的版本。我在画布 API 上使用“mousemove”。我认为胖箭头功能应该防止关闭?
  • 这是一个“陈旧的闭包”:stackoverflow.com/questions/53633698/…
  • 如果将[count] 添加到依赖数组中,那么它将计数设置为 10000 并立即重新渲染。
  • 如果我将[count] 添加到依赖数组中,则每次count 更改时都会添加点击监听器。

标签: reactjs use-state


【解决方案1】:

是的,这是意料之中的,但我能理解为什么它看起来很奇怪。

当您在 useEffect 挂钩中添加 ref 时,您将关闭 count 的值并将其保存以备后用,因此当您单击 sub 时,它会显示组件初始化时的值。

如果你想提醒 count 的实际值可以在 div 中添加onClick={()=&gt;alert(count)},这也更符合 React 的声明式风格。

不鼓励在 React 中使用 refs,因为 React 维护一个虚拟 dom。当需要直接访问 dom 元素时使用 refs。

编辑:您也可以将其用于鼠标移动事件:

https://reactjs.org/docs/events.html#mouse-events

在功能组件的body中单独编写handler函数,并传递给canvas元素的onMouseMoveprop。

【讨论】:

  • 你好!我没有意识到我可以直接在元素上使用onMouseMove。为我工作。谢谢。
猜你喜欢
  • 2023-01-29
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
  • 2022-01-06
相关资源
最近更新 更多