簡體   English   中英

新事件沒有上一個事件更新的最新 state 值

[英]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 並開始移動鼠標時,我看不到更新的 position,其中 y 等於 100。相反,我有初始 state 值,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>
  );
};  

您的代碼不起作用,因為每次重新渲染組件時都會創建新的事件處理函數實例,並且事件偵聽器具有 function 的舊引用,該引用是在組件安裝后創建的。

添加事件處理函數作為useEffect的依賴項並刪除清理 function 中的事件。

以下代碼應該可以正常工作。

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/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM