React实现倒计时功能组件
故事背景
倒计时(或者时间显示)是日常开发中的常见任务
常用在权限控制或者日期显示上
由于经常会使用到,所以将其分装成一个组件,方便以后复用
项目结构搭建
npx create-react-app test-countdown --template=typescript yarn add antd
倒计时组件
1. App.tsx中的内容
// App.tsx /* eslint-disable @typescript-eslint/no-useless-constructor */ import React from 'react'; import { Tooltip, Modal, Button } from "antd"; import './App.css'; // 秒转时间 function convertSecondsToHMS(seconds: number) { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const remainingSeconds = Math.floor(seconds % 60); const formattedTime = `${hours}小时 ${minutes}分钟 ${remainingSeconds}秒`; return formattedTime; } // 倒计时组件props格式 type IProps = { level: boolean; timeRemain: number; } // 倒计时组件state格式 type IState = { level: boolean; timeRemain: number; lastMountedTime: number; timeCountdown: number; timer: any; } // 倒计时组件 class App extends React.PureComponent<IProps, IState> { state = { lastMountedTime: 0, timeRemain: 0, timeCountdown: 9999, level: false, timer: null, } // 多余的构造函数 constructor(props: IProps) { super(props); } // 组件构建完毕之后需要将props中设置的等级,倒计时存到state中去 // 此外还需要将当地时间存到state中去作为之后计算的参考 // 最后开启定时器,并将定时器的handle存到state中去 componentDidMount(): void { const { timeRemain, level } = this.props; const lastMountedTime = +new Date(); const timer = setInterval( () => { this.setState(()=>({ timeCountdown: this.state.timeRemain - (+new Date() - this.state.lastMountedTime) / 1000, })) }, 200 ) this.setState({ lastMountedTime, timeRemain, level, timer, }) } // 在组件卸载之前需要释放定时器 componentWillUnmount(): void { if(this.state.timer) clearInterval(this.state.timer); } // 如果用户是VIP则tooltip上不显示访问剩余时间 // 如果用户是访客,则字体变成红色,tooltip显示倒计时 // 如果倒计时为0则弹出模态框通知用户试用结束 render() { const info = this.state.level ? 'VIP用户' : '访客模式'; const fontColor = this.state.level ? 'black' : 'red'; const timeCountdown = this.state.timeCountdown > 0 ? this.state.timeCountdown : 0; const toolTipInfo = this.state.level ? '' : convertSecondsToHMS(timeCountdown); return ( <div className="App"> { timeCountdown > 0 ? ( <Tooltip title={toolTipInfo} placement="top" > <span style={{ color: fontColor }} >{info}</span> </Tooltip> ) : ( <Modal open={true} destroyOnClose={true} getContainer={() => document.body} onCancel={() => { window.location.replace('') }} closable={true} maskClosable={true} title={`授权到期`} footer={[ <Button size="small" onClick={() => { window.location.replace('') }}> 取消 </Button>, ]} width={215} bodyStyle={{ padding: 0 }} > <div> 您的访客模式到期了 </div> </Modal> ) } </div> ) } } export default App;
2. index.tsx中使用App.tsx
// index.tsx root.render( <App timeRemain={5300} level={false}/> ); // 这里去掉了严格模式
两点内容
1. setInterval只是作为组件内部状态更新的触发器
没有使用定时器的计算值作为渲染的源,因为setInterval
的计算值是不准确的,特别是页面切换到后台的时候;因此使用Date的差值作为计算依据.
2. antd组件Tooltip和Modal的使用
倒计时组件使用antd组件Tooltip和Modal制作,当其访客时间耗尽之后会弹出模态框通知用户退出. 这种交互模式比较友好.
3. 倒计时立即更新
使用this.setState(()=>({}))
而不是this.setState({})
,以确保时间立即更新.
4. 可控FPS
由于1,可知减少触发器setInterval
的间隔,可以使倒计时显示更加丝滑.
到此这篇关于React实现倒计时功能组件的文章就介绍到这了,更多相关React倒计时内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
在 React 中使用 Context API 实现跨组件通信的方法
在React中,ContextAPI是一个很有用的特性,可用于组件间的状态共享,它允许跨组件传递数据而无需通过每个组件手动传递props,本文给大家介绍在 React 中如何使用 Context API 来实现跨组件的通信,感兴趣的朋友一起看看吧2024-09-09使用react-native-image-viewer实现大图预览
这篇文章主要介绍了使用react-native-image-viewer实现大图预览,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-09-09react redux中如何获取store数据并将数据渲染出来
这篇文章主要介绍了react redux中如何获取store数据并将数据渲染出来,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-08-08
最新评论