React Material:带有鼠标监听器的进度条
Posted
技术标签:
【中文标题】React Material:带有鼠标监听器的进度条【英文标题】:React Material: progressBar with mouse listener 【发布时间】: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 的情况下忽略删除?
【问题讨论】:
提供在线演示可以帮助其他人快速了解您面临的问题 【参考方案1】:尝试将React.useCallback
用于updateMousePosition
。组件中的每次更改都会创建新功能(参考)。所以React.useEffect
删除最后一个updateMousePosition
但不删除添加在handleChange
中。
【讨论】:
我应该如何使用它?我不明白,回调应该什么时候执行 请阅读React.useCallbackconst updateMousePosition = React.useCallback(() => setCompleted(old => old + 1); , []);
我忘记了 useEffect dep。将updateMousePosition
添加到 dep 数组。 [completed, updateMousePosition]
那么,当我们在useEffect中添加依赖时,只有在完成更改时才会调用,并且updateMousePosition发生了变化?而且updateMousePosition不会改变(感谢useCallback),所以useEffect只有在完成改变时才会调用?
没错。 useEffect 只会在这种情况下调用。以上是关于React Material:带有鼠标监听器的进度条的主要内容,如果未能解决你的问题,请参考以下文章
打字稿:React.forwardRef 带有来自@material-ui 的通用道具
使用带有 Material-UI 自动完成功能的 react-hook-form 控制器的正确方法
在 React 功能组件中使用 ref 添加测试鼠标事件监听器