如何实现无需刷新页面的实时访客计数器?(TypeScript)
实现无需刷新的实时访客计数器
当然可以实现无需刷新页面就能让访客数实时更新的功能。你当前的代码只在组件首次挂载时请求一次统计接口,所以无法自动获取最新数据。下面是具体的修改步骤和优化方案:
核心修改点
1. 添加定时轮询机制
通过setInterval定期调用统计接口,获取最新的访客数并更新状态。这样就能实现每隔一段时间自动刷新数据。
2. 清理定时器防止内存泄漏
组件卸载时一定要清除定时器,避免不必要的资源消耗和潜在的bug。
3. 设置初始状态避免undefined
给useState设置初始值,防止组件渲染时visitor?.count显示undefined的问题。
4. 处理请求竞态问题(可选但推荐)
使用AbortController取消未完成的请求,避免旧请求返回后覆盖新的状态。
修改后的完整代码
type VisitorType = { count: number; }; const Footer = () => { // 设置初始状态,避免undefined const [visitor, setVisitor] = useState<VisitorType>({ count: 0 }); useEffect(() => { // 定义请求访客数的函数 const fetchVisitorCount = async () => { const controller = new AbortController(); const signal = controller.signal; try { const response = await fetch('https://count.cab/hit/ghG6Oirn0b', { signal }); const data = await response.json(); setVisitor(data); } catch (error) { // 忽略取消请求的错误 if ((error as Error).name !== 'AbortError') { console.log(error); } } }; // 首次加载时请求一次 fetchVisitorCount(); // 设置定时器,每隔30秒请求一次(可根据需求调整间隔) const intervalId = setInterval(fetchVisitorCount, 30000); // 组件卸载时清除定时器 return () => { clearInterval(intervalId); }; }, []); return ( <GridItem w="100%" h={{ base: "80px", lg: "300px" }} colSpan={{ base: 8, lg: 4 }} > <VStack align={{ base: "center", lg: "stretch" }} marginTop={{ base: "0", lg: "60px" }} marginLeft={{ base: "0", lg: "50px" }} > <Box w={{ base: "100px", lg: "220px" }} paddingBottom="10px"> <Image src={imgLogoMd} alt="Logo" w="100%" /> <HStack> <Text fontSize={{ base: "xs", lg: "md" }} textAlign="justify"> {visitor.count} Visitor{visitor.count !== 1 && 's'} </Text> </HStack> </Box> </VStack> </GridItem> ); };
额外优化说明
- 定时器间隔:示例中用了30秒,你可以根据实际需求调整(比如10秒或60秒),不要设置过短,避免给统计服务器造成过大压力。
- 复数处理:添加了
{visitor.count !== 1 && 's'},当访客数大于1时自动显示"Visitors",更符合语法习惯。 - 请求错误处理:忽略了
AbortError,因为取消请求是正常的清理操作,不需要报错。
内容的提问来源于stack exchange,提问作者Estherak23
相关产品推荐
相关产品推荐

