使用状态递增 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.
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.