【问题标题】:How to pass correct state value into callback function inside useEffect hook?如何将正确的状态值传递给 useEffect 挂钩内的回调函数?
【发布时间】:2021-03-12 04:32:00
【问题描述】:

当用户按箭头键或单击图像时,我正在尝试更改保存照片 ID 的变量的状态,然后根据该照片 ID 呈现我的图像。 p>

代码:

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;

通过单击/取消单击图像来设置状态没有问题,状态设置为正确的数字。

但是我处理 keydown 事件的函数被返回,因为我的状态 currentPhotoId 为空,当我通过选择图像设置状态时,我不明白为什么

如果我在 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(点击)功能。而且用户按右箭头键的次数越多它更新状态的次数越多,导致更新过多,最终导致网站崩溃

我做错了什么?为什么我的状态没有正确更新?

【问题讨论】:

    标签: javascript reactjs react-hooks use-effect


    【解决方案1】:

    修复:

    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 中我在调用我的函数时犯了一个错误,而不是调用它,这只是将事件侦听器添加到无限。

    在我的回调函数中,我没有将状态作为参数传递,而是添加了 id 作为依赖项。

    另外,我已经将 selectImage 和 changeImage 分成两个 useEffects,对于 selectImage useEffect 我没有 currentPhotoId 作为依赖项。

    如果有人想详细说明细节,请随时这样做。

    【讨论】:

      猜你喜欢
      • 2020-08-15
      • 1970-01-01
      • 2021-05-28
      • 2021-05-30
      • 2021-03-16
      • 2021-01-29
      • 1970-01-01
      • 2020-07-22
      • 2019-12-16
      相关资源
      最近更新 更多