reactjs - 反应超时和清除超时
问题描述
我有一个未设置为组件的 React 页面。我正在寻找使用 React HooksuseEffect
或任何其他建议。基本上我需要清除我的超时。
const ExamplePage = ({
test1, test2, test3
}: Props) => {
const setClipboardTimer = (index, copied, show, delay) => {
const timer = setTimeout(() => {
setClipboardData(index, copied, show);
}, delay);
// How can I clear my timer on componentWillUnmount
};
const copyToClipboard = (copy, index) => {
copyTextToClipboard(copy);
setClipboardData(index, true, true);
setClipboardTimer(index, true, false, 2500);
setClipboardTimer(index, false, true, 3000);
};
};
解决方案
由于我不知道其他函数在状态方面做了什么(如 copyTextToClipboard、setClipboardData ...等),因此使用和测试计时器的更简单方法是使用组件类。
例如,这是一个简单的组件类,它将渲染延迟 5 秒:
class Timer extends Component {
state = { requestTimeout: false };
// **optional** only rerenders the component if the requestTimeout state has been changed
// this ensures that other state/props changes and/or a parent component
// that has its own updating state, won't update this component
shouldComponentUpdate = (nextProps, nextState) =>
nextState.requestTimeout !== this.state.requestTimeout);
// if the component unloads before the 5000ms timeout, clear it
componentWillUnmount = () => this.clearTimer();
// a class field to clear the timer that was set in this.requestTimeout
clearTimer = () => clearTimeout(this.requestTimeout);
// a class field to update state and clear the timeout
requestTimedout = () =>
this.setState({ requestTimeout: true }, () => this.clearTimer());
// a class field to set this.requestTimeout to a timer that will trigger
// this.requestTimedout after a 5000ms delay
setRequestTimer = () =>
this.requestTimeout = setTimeout(this.requestTimedOut, 5000);
// if requestTimeout state is true (?) show hello (:) else show loading
render = () => this.state.requestTimeout ? <p>Hello</p> : <p>Loading...</p>
}
当您开始处理钩子时,您将需要一种方法来保持相同的计时器,当/如果在计时器仍在运行时更新已安装的功能组件(否则,它会在每次功能组件时继续创建新的计时器重新渲染)。
例如,我在这里有一个演示,其中涉及使用setIterval
. 如您所见(单击源< >
按钮),它涉及在功能组件的状态已更新时使用useRef
对象来保持相同的计时器。setInterval
然后,我利用几个回调函数来设置/暂停/清除间隔。此外,它利用useEffect
钩子检查它是否仍在运行,如果是,它将在return
语句中清除它。
简而言之,虽然您可以从我的 setIterval 钩子演示中使用 a 实现相同的目的setTimeout
,但我发现类更易于使用和理解(尤其是当状态正在更新并且需要同步处理时)。
推荐阅读
- php - 如何在php中将数组合并为单个数组?
- python - ValueError: x 和 y 必须具有相同的第一维,但具有形状 (50,) 和 (1, 50)/ 多处理
- monaco-editor - 覆盖摩纳哥编辑器悬停小部件样式以隐藏“偷看问题”
- go - go-swagger:没有可用于解组的规范
- python - 在 Python 中的 mysql 连接中出现错误
- javascript - 删除显示的项目列表的问题
- python - 格式不显示
- c# - 如何仅过滤和搜索选定字段并排除 ASP.NET MVC 中的空文本框
- mysql - 使用 Intellij 通过 kubernetes pod 连接到 MySQL 服务器
- django - 获取子查询的计数