新事件没有由上一个事件更新的最新状态值

New event doesn't have latest state value updated by previous event

情况是这样的,

const MyComp = () => {
    const timelineOverlayRef = useRef(null);
    const [position, setPosition] = useState({ x: 0, y: 0 });

    const mouseDownHandler = e => {
        setPosition({ x: 0, y: 100});
    };

    const mouseMoveHandler = e => {
        console.log(position);
    }

    const init = () => {
        timelineOverlayRef.current.addEventListener('mousemove', mouseMoveHandler);

        timelineOverlayRef.current.addEventListener('mousedown', mouseDownHandler);

    }

    useEffect(init, []);

    return <div ref={timelineOverlayRef}>My Div where I want to capture mouse down and mouse move events</div>;
}

当我点击我的 div 并开始移动鼠标时,我没有看到 y 等于 100 的更新位置。相反,我有 y = 0 的初始状态值。知道为什么会这样可能会发生,如何克服这个问题将不胜感激。

在 div 上使用 onMouseMoveonMouseDown 事件。

const MyComp = () => {
  const timelineOverlayRef = useRef(null);
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const mouseDownHandler = e => {
    setPosition({ x: 0, y: 100 });
  };

  const mouseMoveHandler = e => {
    console.log(position);
  };

  return (
    <div
      ref={timelineOverlayRef}
      onMouseMove={mouseMoveHandler}
      onMouseDown={mouseDownHandler}
    >
      My Div where I want to capture mouse down and mouse move events
    </div>
  );
};  

您的代码无法正常工作,因为每次组件重新呈现时都会创建事件处理程序函数的新实例,并且事件侦听器具有对组件安装后创建的函数的旧引用。

将事件处理函数添加为 useEffect 的依赖项并删除清理函数中的事件。

以下代码应该可以正常工作。

const MyComp = () => {
  const timelineOverlayRef = useRef(null);
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const mouseDownHandler = e => {
    console.log("clicked...");
    setPosition({ x: 0, y: 100 });
  };

  const mouseMoveHandler = e => {
    console.log(position);
  };

  const init = () => {
    timelineOverlayRef.current.addEventListener("mousemove", mouseMoveHandler);
    timelineOverlayRef.current.addEventListener("mousedown", mouseDownHandler);

    return () => {
      timelineOverlayRef.current.removeEventListener(
        "mousemove",
        mouseMoveHandler
      );
      timelineOverlayRef.current.removeEventListener(
        "mousedown",
        mouseDownHandler
      );
    };
  };

  useEffect(init, [mouseDownHandler, mouseMoveHandler]);

  return (
    <div ref={timelineOverlayRef}>
      My Div where I want to capture mouse down and mouse move events
    </div>
  );
};  

为了简化上面的代码,您可以使用这个自定义钩子:https://usehooks.com/useEventListener/