我仅在用户将鼠标悬停在图标上一秒钟之后才尝试打开弹出窗口,以防止意外触发它。
我发现做到这一点的唯一方法是在处理程序函数上使用setTimeout,问题是,要使其正常工作,我必须向React组件声明一个全局变量。这行得通,但我宁愿不以这种方式使用全局变量。
let timer;
export default class Users extends Component {
state = {
popoverOpen: false,
};
handleMouseOver = (e) => {
e.stopPropagation();
switch (e.type) {
case 'mouseover':
clearTimeout(timer);
timer =
setTimeout(() => {
this.setState({
popoverOpen: true
});
}, 1000);
break;
case 'mouseout':
clearTimeout(timer);
break;
default:
console.log(e.type);
break;
}
};
是否有一种方法可以使用本地状态设置和清除超时,或者如果没有更好的方法可以使我逃避呢?
谢谢。
答案 0 :(得分:2)
使用上层类来存储计时器和状态数据,如下所示:
class A {
constructor() {
this.state = false;
}
func() {
if (this.state) {
console.log('push the call');
clearTimeout(this.timer);
} else {
console.log('initial call');
}
this.state = true;
this.timer = setTimeout(() => {
this.state = false;
console.log('Call ended');
}, 500);
};
};
const a = new A();
a.func();
for (let i = 0; i < 5; i += 1) {
setTimeout(() => a.func(), i * 200);
}
或者如果您不想污染您的类,请将函数包装在可以存储数据的IIFE内
我创建了一个片段示例,然后创建了一个可用的react示例以放入您的代码中(因为handleMouseOver = (e) => {
在纯js中不起作用)
class A {};
const a = new A();
a.func = (() => {
let state = false;
let timer;
return () => {
if (state) {
console.log('push the call');
clearTimeout(timer);
} else {
console.log('initial call');
}
state = true;
timer = setTimeout(() => {
state = false;
console.log('Call ended');
}, 500);
};
})();
for (let i = 0; i < 5; i += 1) {
setTimeout(() => a.func(), i * 200);
}
class A {
func = (() => {
let state = false;
let timer;
return () => {
if (state) {
console.log('push the call');
clearTimeout(timer);
} else {
console.log('initial call');
}
state = true;
timer = setTimeout(() => {
state = false;
console.log('Call ended');
}, 500);
};
})();
};