[英]How to pass correct state value into callback function inside useEffect hook?
我正在尝试更改当用户按下箭头键或单击图像时保存照片 ID 的变量的 state ,然后根据该照片 ID 渲染我的图像。
代码:
const Lightbox = ({ filteredPhotos }) => {
const [currentPhotoId, setCurrentPhotoId] = useState(null);
const currentPhoto = filteredPhotos.filter((photo) => photo.strapiId === currentPhotoId)[0];
let lightbox = "";
const getLastPhotoId = (filteredPhotos) => {
const ids = filteredPhotos.map((item) => item.strapiId).sort((a, b) => a - b);
const result = ids.slice(-1)[0];
return result;
};
//Select image on click
const selectImage = useCallback(
(e) => {
const divId = parseInt(e.target.parentElement.parentElement.className.split(" ")[0]);
const imgSelected = e.target.parentElement.parentElement.className.includes("gatsby-image-wrapper");
imgSelected && divId !== NaN ? setCurrentPhotoId(divId) : setCurrentPhotoId(null);
},
[setCurrentPhotoId]
);
//Change image on keypress
const changeImage = useCallback(
(e, currentPhotoId) => {
if (document.location.pathname !== "/portfolio" || currentPhotoId === null) return;
const key = e.keyCode;
console.log("changeImage start: ", currentPhotoId);
if (key === 27) {
setCurrentPhotoId(null);
} else if (key === 39) {
setCurrentPhotoId(currentPhotoId + 1);
} else if (key === 37) {
if (currentPhotoId - 1 <= 0) {
setCurrentPhotoId(getLastPhotoId(filteredPhotos))
} else {
setCurrentPhotoId(currentPhotoId - 1)
}
}
},
[setCurrentPhotoId]
);
useEffect(() => {
const gallery = document.getElementById("portfolio-gallery");
gallery.addEventListener("click", (e) => selectImage(e));
document.addEventListener("keydown", (e) => changeImage(e, currentPhotoId));
}, [selectImage, changeImage]);
useEffect(() => {
console.log(currentPhotoId);
}, [currentPhotoId]);
return currentPhotoId === null ? (
<div id="lightbox" className="lightbox">
<h4>Nothing to display</h4>
</div>
) : (
<div id="lightbox" className="lightbox lightbox-active">
<img src={currentPhoto.photo.childImageSharp.fluid.src} alt={currentPhoto.categories[0].name} />
</div>
);
};
export default Lightbox;
通过单击/取消单击图像设置 state 没有问题,state 设置为正确的数字。
But my function that handles keydown events is returned because my state currentPhotoId is null, and I don't get it why when I've set my state by selecting an image.
如果我在 useEffect 依赖数组中添加 currentPhotoId
useEffect(() => {
const gallery = document.getElementById("portfolio-gallery");
gallery.addEventListener("click", (e) => selectImage(e));
document.addEventListener("keydown", (e) => changeImage(e, currentPhotoId));
}, [selectImage, changeImage, currentPhotoId]); //here
它破坏了我的 selectImage(单击)function。 而且用户按右箭头键的次数越多,它更新 state 的次数就越多,导致更新太多,最终导致网站崩溃。
我究竟做错了什么? 为什么我的 state 没有正确更新?
使固定:
useEffect(() => {
document.addEventListener("keydown", changeImage); //invoking not calling
return () => {
document.removeEventListener("keydown", changeImage);
};
}, [changeImage, currentPhotoId]);
const changeImage = useCallback(
(e) => {
if (document.location.pathname !== "/portfolio" || currentPhotoId === null) return;
const key = e.keyCode;
if (key === 27) {
setCurrentPhotoId(null);
} else if (key === 39) {
setCurrentPhotoId(currentPhotoId + 1);
} else if (key === 37) {
if (currentPhotoId - 1 <= 0) {
setCurrentPhotoId(getLastPhotoId(filteredPhotos));
} else {
setCurrentPhotoId(currentPhotoId - 1);
}
}
},
[setCurrentPhotoId, currentPhotoId] //added currentPhotoId as dependency
);
因此,在 useEffect 中,我在调用 function 时犯了一个错误,而不是调用它,这只是将事件侦听器添加到无限。
在我的回调 function 中,我没有将 state 作为参数传递,而是添加了 id 作为依赖项。
另外,我将 selectImage 和 changeImage 分成两个 useEffects,对于 selectImage useEffect 我没有 currentPhotoId 作为依赖项。
如果有人想详细说明细节,请随时这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.