【问题标题】:React Material: progressBar with mouse listenerReact Material:带有鼠标监听器的进度条
【发布时间】:2020-07-08 00:09:33
【问题描述】:


我在使用 React 和 React Material-UI 组件时遇到了问题。我需要什么:

1) 用户单击我的组件中的按钮 - 我应该将 mousemove 侦听器添加到页面并显示 ProgressBar。
2) 用户移动鼠标 - 我计算事件,并更新我的 ProgressBar。
3) 当事件计数为 50 时,我删除 mousemove 侦听器并隐藏 ProgressBar。

我尝试使用 React useEffect、useState Hooks 来执行此操作,但它不会删除侦听器。我不明白,为什么。

这是我的代码:

  const [completed, setCompleted] = React.useState(0);
  const [keyGenState, setKeyGenState] = React.useState(0);

  const updateMousePosition = ev => {
    console.log("UMP");
    setCompleted(old => old + 1);
    /*I tried to check completed value here, but it always is 0 - maybe, React re-renders component on setState..
    And I decided to take useEffect hook (see below)*/
  };

  useEffect(() => {
    console.log(completed); /*Just to understand, what happens) */
    if (completed === 49) {
        return () => {
            /*When completed value is 50, this log message appears, but mouse listener still works! */
            console.log("Finish!");
            document.removeEventListener("mousemove", updateMousePosition);
            setKeyGenState(2);
          }
    }
  }, [completed]); 

  function handleChange(e) {
    switch (e.currentTarget.id) {
        /*startKeyGen - it is ID of my Button. When user clicks it, I show ProgressBar and add mousemove listener*/
        case "startKeyGen" : {
            setKeyGenState(1);
            document.addEventListener("mousemove", updateMousePosition);
            break;}
    }
  }

/*Other logics. And finally, JSX code for my ProgressBar from Material-UI*/
<LinearProgress hidden={keyGenState !== 1 } variant="determinate" value={completed} style={{marginTop: 10}} />


看起来真的很奇怪:为什么 React 会忽略 removeEventListener。
请解释一下,我的错误在哪里。
UPD: 非常感谢!我以这种方式使用了 useCallback 钩子:

  const updateMousePosition = React.useCallback(
(ev) => {
      //console.log("Calback");
      console.log(ev.clientX);
      setCompleted(old => old + 1);
    },
  [],
);
useEffect(() => {
  //console.log(completed); /*Just to understand, what happens) */
  if (completed === 49) {
      return () => {
        /*When completed value is 50, this log message appears, but mouse listener still works! */
          console.log("Finish!");
          document.removeEventListener("mousemove", updateMousePosition);
          setKeyGenState(2);
        }
  }
}); 


但我仍然不完全理解.. 所以,当我使用带有空依赖项数组的 useCallback 时,这个函数 (updateMousePosition) 在我的组件的所有“生命”期间都将保持不变?
在 useEffect 中我删除了 mouseListener。这对我来说很神奇:为什么 useEffect 在没有 useCallback 的情况下忽略删除?

【问题讨论】:

  • 提供在线演示可以帮助其他人快速了解您面临的问题

标签: javascript reactjs react-hooks react-material


【解决方案1】:

尝试将React.useCallback 用于updateMousePosition。组件中的每次更改都会创建新功能(参考)。所以React.useEffect 删除最后一个updateMousePosition 但不删除添加在handleChange 中。

【讨论】:

  • 我应该如何使用它?我不明白,回调应该什么时候执行
  • 请阅读React.useCallback const updateMousePosition = React.useCallback(() =&gt; { setCompleted(old =&gt; old + 1); }, []);
  • 我忘记了 useEffect dep。将updateMousePosition 添加到 dep 数组。 [completed, updateMousePosition]
  • 那么,当我们在useEffect中添加依赖时,只有在完成更改时才会调用,并且updateMousePosition发生了变化?而且updateMousePosition不会改变(感谢useCallback),所以useEffect只有在完成改变时才会调用?
  • 没错。 useEffect 只会在这种情况下调用。
猜你喜欢
  • 2013-07-20
  • 2014-12-13
  • 2014-02-21
  • 1970-01-01
  • 1970-01-01
  • 2012-03-30
  • 2020-05-15
  • 2015-11-30
  • 2011-01-01
相关资源
最近更新 更多