React + TypeScript:将 setTimeout() 与 Hooks 一起使用
这篇简洁实用的文章将向您介绍在使用TypeScript编写的 React 应用程序中使用window.setTimeout() 和window.clearTimeout() 方法的完整示例。我们将使用带有钩子的功能组件(useState、useEffect和useRef)。你不会看到像类组件、this.setState 或类似的东西这样的老式东西。
简要概述
setTimeout() 方法用于在几毫秒后触发一个函数。它返回一个类型为number的 id。您可以使用此id和clearTimeout() 方法来停止由setTimeout() 设置的计时器:
let myTimer: number;
// setTimeout
myTimeout = window.setTimeout(() => {/* ...*/}, 3000);
// clearTimeout
window.clearTimeout(myTimer);
在上面的代码片段中,您可以注意到我们显式调用了window.setTimeout() 和window.clearTimeout() 。此操作告诉 TypeScript 我们正在为前端 Web 应用程序编写代码。
在现代 React 中,您可以将setTimeout() 与钩子一起使用,如下所示:
// use ref to store the timer id
const refTimer = useRef<number | null>(null);
// trigger the timer
const startTimer = () => {
if (refTimer.current !== null) return;
refTimer.current = window.setTimeout(() => {
/* do something here */
}, 5000);
};
// stop the timer
const stopTimer = () => {
if (refTimer.current === null) return;
window.clearTimeout(refTimer.current);
refTimer.current = null;
};
// Cleanup function to clear the timer when the component unmounts
useEffect(() => {
// cleanup function
return () => {
if (refTimer.current !== null) {
window.clearTimeout(refTimer.current);
}
};
}, []);
为了更好地理解,请参阅下面的端到端工作示例。
注意:setTimeout() 方法只执行一次。如果您需要重复执行,请改用setInterval()方法
这个例子
应用预览
我们要使用的演示项目有 2 个按钮:
- 显示:此按钮为绿色。当它被按下时,将设置一个计时器,5 秒后,将出现一个蓝色框。在这 5 秒期间,该按钮被禁用以防止用户与其交互。
- 取消:一开始,此按钮被禁用。它仅在计时器运行时启用。您可以使用此按钮停止计时器。
下面的动画 GIF 截图清楚地描述了我的意思:
编码
- 创建一个完全支持 TypeScript 的 React 项目:
npx create-react-app kindacode-example
会生成很多文件和文件夹,但请注意这两个文件:src/App.tsx和src/App.css。
2. 将App.tsx中的所有默认代码替换为以下内容(您可以在评论中找到解释):
// Kindacode.com
// App.tsx
import React, { useState, useEffect, useRef } from 'react';
import './App.css';
const App = () => {
// show/hide state of the box
const [isShown, setIsShown] = useState(false);
// the timer is set or not
const [isRunning, setIsRunning] = useState(false);
// use ref to store the timer id
const refTimer = useRef<number | null>(null);
// show the box after 5 seconds
const showBox = () => {
if (refTimer.current !== null) return;
setIsRunning(true);
refTimer.current = window.setTimeout(() => {
setIsShown(true);
setIsRunning(false);
}, 5000);
};
// prevent the box from being shown by clearing the timer
const stopTimeout = () => {
if (refTimer.current === null) return;
window.clearTimeout(refTimer.current);
refTimer.current = null;
setIsRunning(false);
};
// Cleanup function to clear the timer when the component unmounts
useEffect(() => {
// cleanup function
return () => {
if (refTimer.current !== null) {
window.clearTimeout(refTimer.current);
}
};
}, []);
return (
<div className='container'>
<div className='buttons'>
{/* This button is used to start the timer */}
<button
disabled={isRunning || isShown}
onClick={showBox}
className='button-show'
>
Show
</button>
{/* This button is used to cancel the timer */}
<button
disabled={!isRunning}
onClick={stopTimeout}
className='button-stop'
>
Cancel
</button>
</div>
{/* Some useful messages */}
{!isRunning && !isShown && (
<p>Click the "Show" button and wait 5 seconds to see the blue box</p>
)}
{isRunning && (
<p>Press the "Cancel" button to prevent the box from shows up</p>
)}
{/* The box */}
{isShown && (
<div className='box'>
<h1>Welcome to KindaCode.com</h1>
</div>
)}
</div>
);
};
export default App;
3. 擦除App.css中所有不需要的 CSS 代码,然后添加以下内容:
/* App.css */
.container {
width: 80%;
margin: 10px auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
/* Style the buttons */
.buttons {
margin-top: 20px;
display: flex;
justify-content: center;
}
.button-show {
margin: 0 10px;
padding: 10px 20px;
background: #4caf50;
color: white;
border: none;
cursor: pointer;
}
.button-show:hover {
background: #43a047;
}
.button-show:disabled {
background: #ccc;
cursor: not-allowed;
}
.button-stop {
margin: 0 10px;
padding: 10px 20px;
background: #f44336;
color: white;
border: none;
cursor: pointer;
}
.button-stop:hover {
background: #e53935;
}
.button-stop:disabled {
background: #ccc;
cursor: not-allowed;
}
/* Style the box */
.box {
margin-top: 50px;
width: 100%;
height: 200px;
display: flex;
align-items: center;
justify-content: center;
background: #2196f3;
color: white;
}
- 最后要做的是启动它并在 http://localhost:3000 检查结果:
npm start
总结
这是一个小而有意义的项目,它使用了window.setTimeout() 方法、React 钩子和 TypeScript。尝试修改代码,进行一些更改,调整一些值,然后看看会发生什么结果。