繁体   English   中英

如何将正确的 state 值传递给 useEffect 挂钩内的回调 function?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM