reactjs - setInterval 不在 React 功能组件中
问题描述
我做了一个 React 组件,可以在必要时将内容滚动到页面顶部,如果您查看代码沙箱示例,如果向下滚动一点会显示“GO Top”按钮,如果单击它,页面将滚动到顶部,如果您尝试向下滚动,它总是会将您带到页面顶部。原因是没有清除计时器,因为 intervalId 始终为空。具体来说,如果您查看第 20 行,intervalId 始终为空,我想这可能与关闭有关,但我无法修复它。请帮忙。
谢谢!
代码贴在下面,codesanbox 示例在这里
import React from "react";
const GoTop = ({ scrollStepInPx, delayInMs }) => {
const [intervalId, setIntervalId] = React.useState(null);
const [position, setPosition] = React.useState(false);
React.useEffect(() => {
document.addEventListener("scroll", () => {
if (window.scrollY > 200) {
setPosition(true);
} else {
setPosition(false);
}
});
window.scrollTo(0, 0);
}, []);
const onScrollStep = () => {
if (window.pageYOffset === 0) {
console.log(intervalId); //always null
clearInterval(intervalId);
return;
}
window.scroll(0, window.pageYOffset - scrollStepInPx);
};
const scrollToTop = () => {
const id = setInterval(onScrollStep, delayInMs);
setIntervalId(() => id);
};
const renderGoTopIcon = () => {
if (position) {
return (
<button className="go-top" onClick={scrollToTop} type="button">
Go Top
</button>
);
}
return null;
};
return <>{renderGoTopIcon()}</>;
};
export default GoTop;
解决方案
我让它像这样工作,这篇文章有帮助。 https://dmitripavlutin.com/react-hooks-stale-closures/
import React from "react";
const GoTop = ({ scrollStepInPx, delayInMs }) => {
const [position, setPosition] = React.useState(false);
React.useEffect(() => {
document.addEventListener("scroll", () => {
if (window.scrollY > 200) {
setPosition(true);
} else {
setPosition(false);
}
});
window.scrollTo(0, 0);
}, []);
const scrollToTop = () => {
let intervalId;
//move the event handle here, NOT use hooked state variable intervalId
const onScrollStep = () => {
if (window.pageYOffset === 0) {
clearInterval(intervalId);
return;
}
window.scroll(0, window.pageYOffset - scrollStepInPx);
};
intervalId = setInterval(onScrollStep, delayInMs);
};
const renderGoTopIcon = () => {
if (position) {
return (
<button className="go-top" onClick={scrollToTop} type="button">
Go Top
</button>
);
}
return null;
};
return <>{renderGoTopIcon()}</>;
};
export default GoTop;
推荐阅读
- javascript - 单击时使用 javascript 增加按钮文本?
- javascript - 如何在 django rest 框架中将错误响应发送回客户端?
- xpath - 如何为肥皂标题和正文创建 xPath
- javascript - 如何通过 onclick chilld 组件将数据传递给父组件反应
- spark-structured-streaming - Spark Structured Streaming:使用 hdfs 检查点位置读取增量文件时出错
- javascript - 在提交之前将值传递给隐藏的输入值
- powershell - 从快捷方式启动时,Powershell 脚本崩溃
- r - R中ggplot2中多个图例的图例键之间的间距
- python - 创建后如何杀死类的实例以释放python中的内存?
- javascript - 将复杂对象从视图发送到 MVC 操作作为无 ajax 调用