使用状态递增 1 在 setInterval 中不起作用

Usestate increment by 1 not working in setInterval

    const [currentPage, setCurrentPage] = useState(1);     
    const handleScroll = () => {
            const gridContainer = document.querySelector(".grid");
    
            const totalPages = Math.ceil(
                gridContainer.scrollWidth / gridContainer.clientWidth + -0.1
            );
            setTotalPages(totalPages);
    
            const scrollPos =
                gridContainer.clientWidth + gridContainer.scrollLeft + 2;
            if (gridContainer.scrollWidth > scrollPos) {
                gridContainer.scrollBy({
                    left: gridContainer.clientWidth + 20.5,
                    behavior: "auto",
                    block: "center",
                    inline: "center",
                });
                setCurrentPage(currentPage + 1);
            } else {
                setCurrentPage(1);
                gridContainer.scrollTo(0, 0);
            }
        };
    
        useEffect(() => {
            setInterval(() => {
                document.querySelector(".grid") && handleScroll();
            }, 5000);
        }, []);

出于某种原因,当我 运行 setCurrentPage 但如果我像这样增加它时,这永远不会超过两个

 <button onClick={() => setCurrentPage(currentPage + 1)}>
                    +1
  </button

它按预期工作。我猜它与 useEffect 或 setInterval 有关,但不能 100% 确定原因。

一个新的 handleScroll 函数会在您的代码中的每个渲染器上创建。

函数只是第一次传给了setInterval,所以这个函数里面的currentPage永远是1,那么1 + 1永远是2.

(A) 将handleScroll放入依赖数组

一个解决方案是在有新的 handlescroll:

时创建一个新的 setInterval
    useEffect(() => {
        let interval = setInterval(() => {   // <--- store the interval (to be able to remove it later)
            document.querySelector(".grid") && handleScroll();
        }, 500);

        // -- remove the interval inside the clean up function of useEffect
        return () => {
            clearInterval( interval );
        }
    }, [ handleScroll ]); // <--- add handleScroll to the dependency array

显然,在这种情况下,setTimeout 可能是更好的选择,因为它总是只运行一次。

(B) 传递一个函数给setState

或者您可以 pass a function to setState:

setCurrentPage((prevCurrentPage) => prevCurrentPage + 1);

也就是一般完全可以,但注意不要lie about your effect’s dependencies.