使用 useEffect 反应 addEventListener 问题
React addEventListener issue with useEffect
我正在制作一个带有 React 的自定义图像查看器,我想使用键盘的左箭头和右箭头来实现图像导航
注:currentId为当前可见的图片id
useEffect(() => {
document.addEventListener("keydown", function (event) {
if (event.key === "ArrowRight") {
setLoaded(false);
if (currentId + 1 < props.imgs.length) {
console.log("right");
setcurrentId(currentId + 1);
} else if (currentId + 1 === props.imgs.length) {
setcurrentId(0);
}
}
if (event.key === "ArrowLeft") {
setLoaded(false);
if (currentId - 1 >= 0) {
console.log("left");
setcurrentId(currentId - 1);
} else if (currentId - 1 === -1) {
setcurrentId(props.imgs.length - 1);
}
}
});
}, [currentId]);
现在的问题是,当我按下键盘 right/left 箭头键时
console.log()
每次都使用随机数执行多次,我知道每次状态更新可能是 运行 但不知道如何修复它。
虽然当我将 [currenId]
添加到 useEffect
时,图像导航可以正常工作,但控制台仍然看起来像这样,使导航变慢
我也尝试过不使用 [currentId]
作为第二个参数。当我这样做时,它会记录这个
并在 ArrowRight 上按下它将 currentId
设置为 1 并且日志的权利只有一次但是当我再次按下时没有做任何事情
并且当按下 ArrowLeft 时,它将 currentId
设置为数组的长度 props.imgs - 1
例如:- props.imgs.length - 1
和日志的 nothing
你一遍又一遍地注册监听器。 React 关于 useHook
的文档提到了如何 clean up 某些事情,这正是事件监听器所需要的:
useEffect(() => {
const listener = function(event) {
// ...
};
document.addEventListener('keydown', listener);
return () => {
// This function gets called when the "effect wears off"
// which means we need to unregister the listener
document.removeEventListener('keydown', listener);
};
}, [currentId]);
[currentId]
使得 React 只在 currentId
发生变化时调用钩子。 React 还确保每当组件被卸载,或者钩子将要为同一个组件重新执行时,“清理函数”就会被调用。清理函数基本上是您在钩子中 return 的任何函数。如果您不 return any,则不会调用清理函数。
我正在制作一个带有 React 的自定义图像查看器,我想使用键盘的左箭头和右箭头来实现图像导航
注:currentId为当前可见的图片id
useEffect(() => {
document.addEventListener("keydown", function (event) {
if (event.key === "ArrowRight") {
setLoaded(false);
if (currentId + 1 < props.imgs.length) {
console.log("right");
setcurrentId(currentId + 1);
} else if (currentId + 1 === props.imgs.length) {
setcurrentId(0);
}
}
if (event.key === "ArrowLeft") {
setLoaded(false);
if (currentId - 1 >= 0) {
console.log("left");
setcurrentId(currentId - 1);
} else if (currentId - 1 === -1) {
setcurrentId(props.imgs.length - 1);
}
}
});
}, [currentId]);
现在的问题是,当我按下键盘 right/left 箭头键时
console.log()
每次都使用随机数执行多次,我知道每次状态更新可能是 运行 但不知道如何修复它。
虽然当我将 [currenId]
添加到 useEffect
时,图像导航可以正常工作,但控制台仍然看起来像这样,使导航变慢
我也尝试过不使用 [currentId]
作为第二个参数。当我这样做时,它会记录这个
并在 ArrowRight 上按下它将 currentId
设置为 1 并且日志的权利只有一次但是当我再次按下时没有做任何事情
并且当按下 ArrowLeft 时,它将 currentId
设置为数组的长度 props.imgs - 1
例如:- props.imgs.length - 1
和日志的 nothing
你一遍又一遍地注册监听器。 React 关于 useHook
的文档提到了如何 clean up 某些事情,这正是事件监听器所需要的:
useEffect(() => {
const listener = function(event) {
// ...
};
document.addEventListener('keydown', listener);
return () => {
// This function gets called when the "effect wears off"
// which means we need to unregister the listener
document.removeEventListener('keydown', listener);
};
}, [currentId]);
[currentId]
使得 React 只在 currentId
发生变化时调用钩子。 React 还确保每当组件被卸载,或者钩子将要为同一个组件重新执行时,“清理函数”就会被调用。清理函数基本上是您在钩子中 return 的任何函数。如果您不 return any,则不会调用清理函数。