javascript - Usestate 递增 1 在 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
依赖数组
一个解决方案是在有新的setInterval
时候创建一个新的handlescroll
:
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
显然,在这种情况下 asetTimeout
可能是更好的选择,因为它总是只运行一次。
(B) 将函数传递给 setState
或者,您可以将函数传递给 setState:
setCurrentPage((prevCurrentPage) => prevCurrentPage + 1);
这通常完全没问题,但请注意不要对效果的依赖项撒谎。
推荐阅读
- android - 请求忽略电池优化后如何手动更改电池优化设置?
- go - 走线,连接依赖关系
- r - 在 ggplot 中绘制可变数量的系列以用于 Shiny 应用程序
- python-3.x - 用于提取文本中位置的 geograpy3 库,给出 UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 276
- javascript - 在 JavaScript 中为 URL 创建动态变量
- json - Azure Pipeline - 通过 json 导入任务组总是创建一个新的,而不是更改现有的
- javascript - 解决查询(冗余)数据的最佳方法
- android - 当用户使用 firebase 单击按钮时向其他用户发送通知
- java - 线程“AWT-EventQueue-0”java.lang.IllegalStateException 中的异常:不允许在事件调度线程中阻塞
- sql - 如何检查/选择字符串是否包含表列值中的值?