React中需要多个倒计时的问题
最近有一个需求是做一个闪购列表,列表中每一个商品都有倒计时,如果每一个倒计时都去生成一个setTimeout的话,一个页面就会有很多定时器,感觉这种做法不是非常好,于是换了一个思路。
思路是这样的,一个页面只生成一个定时器。页面利用对象去维护一个回调函数列表,key可以是id等唯一标识,value就是更新时间的函数,我这里用的是setState。提供一个往对象里添加回调函数的方法和一个移除回调函数的方法。
// 用于存放每个倒计时的回调方法
const countDownFuncList = {}; const addFunc = (key, func) => {
countDownFuncList[key] = func;
}
const removeFunc = (key) => {
delete countDownFuncList[key];
}
生成一个定时器,隔一定的时间就去遍历回调函数列表,调用里面的函数。
let intervalHandler = -1;
const countDown = () => {
if (intervalHandler !== -1) {
clearTimeout(intervalHandler);
}
intervalHandler = setTimeout(() => {
const now = new Date();
Object.keys(countDownFuncList).forEach((key) => {
const item = countDownFuncList[key];
if (typeof item === 'function') {
item(now);
}
})
}, 300);
}
具体调用是调用timeContent方法来处理展示的时间。
const timeContent = (millisecond) => {
const second = millisecond / 1000;
let d = Math.floor(second / 86400);
let h = Math.floor((second % 86400) / 3600);
let m = Math.floor(((second % 86400) % 3600) / 60);
let s = Math.floor(((second % 86400) % 3600) % 60);
let countDownDOM;
if (d > 0) {
countDownDOM = (<div class="count-down">{d} 天 {h} : {m} : {s}</div>);
} else {
countDownDOM = (<div class="count-down">{h} : {m} : {s}</div>);
}
return countDownDOM;
}
这个方法有一个缺点就是当前时间的获取,除了初始化步骤以外,之后的更新都是通过new Date()来获取的,这样存在获取的时间可能并不是正确的当前时间的问题。
完整代码如下:
// 用于存放每个倒计时的回调方法
const countDownFuncList = {}; const addFunc = (key, func) => {
countDownFuncList[key] = func;
}
const removeFunc = (key) => {
delete countDownFuncList[key];
} const timeContent = (millisecond) => {
const second = millisecond / 1000;
let d = Math.floor(second / 86400);
let h = Math.floor((second % 86400) / 3600);
let m = Math.floor(((second % 86400) % 3600) / 60);
let s = Math.floor(((second % 86400) % 3600) % 60); let countDownDOM;
if (d > 0) {
countDownDOM = (<div class="count-down">{d} 天 {h} : {m} : {s}</div>);
} else {
countDownDOM = (<div class="count-down">{h} : {m} : {s}</div>);
} return countDownDOM;
} let intervalHandler = -1;
const countDown = () => {
if (intervalHandler !== -1) {
clearTimeout(intervalHandler);
}
intervalHandler = setTimeout(() => {
const now = new Date();
Object.keys(countDownFuncList).forEach((key) => {
const item = countDownFuncList[key];
if (typeof item === 'function') {
item(now);
}
})
}, 300);
} countDown(); class CountDownItem extends React.Component {
constructor(props) {
super(props);
this.state = {
currentTime: this.props.nowDate
} this.parseDisplayTime = this.parseDisplayTime.bind(this);
} componentDidMount() {
const { id } = this.props;
// 往事件列表添加回调函数
addFunc(id, this.updateTime);
} componentWillUnmount() {
const { id } = this.props;
// 从事件列表移除回调函数
removeFunc(id);
} updateTime(time) {
this.setState({
currentTime: time
})
} parseDisplayTime() {
const { endTime, id } = this.props;
const { currentTime } = this.state;
const subtractTime = endTime - currentTime;
let countDownDOM = '';
if(subtractTime > 1000){
countDownTimeDOM = (
<div className="count-down-content">
{timeContent(subtractTime)}
</div>
);
}else{
removeFunc(id);
} return countDownDOM;
} render(){
return(
<div className="count-down-wrap">{this.parseDisplayTime()}</div>
);
}
}
React中需要多个倒计时的问题的更多相关文章
- react中简单倒计时跳转
其实在react中实现倒计时的跳转方法有很多中,其中我认为较为好用的就是通过定时器更改state中的时间值. 首先在constructor中设置10秒的时间值: constructor () { su ...
- 理解React中es6方法创建组件的this
首发于:https://mingjiezhang.github.io/(转载请说明此出处). 在JavaScript中,this对象是运行时基于函数的执行环境(也就是上下文)绑定的. 从react中的 ...
- 【原】React中,map出来的元素添加事件无法使用
在使用react中,经常用到react的map函数,用法和jquery里中的map一样,但是,如果你在每个map出来的元素中添加,你会发觉添加的事件无法关联, 比如,我们很多的评论,我需要在每个评论下 ...
- React中props.children和React.Children的区别
在React中,当涉及组件嵌套,在父组件中使用props.children把所有子组件显示出来.如下: function ParentComponent(props){ return ( <di ...
- Immutable 详解及 React 中实践
本文转自:https://github.com/camsong/blog/issues/3 Shared mutable state is the root of all evil(共享的可变状态是万 ...
- React中父组件与子组件之间的数据传递和标准化的思考
React中父组件与子组件之间的数据传递的的实现大家都可以轻易做到,但对比很多人的实现方法,总是会有或多或少的差异.在一个团队中,这种实现的差异体现了每个人各自的理解的不同,但是反过来思考,一个团队用 ...
- React中使用CSSTransitionGroup插件实现轮播图
动画效果,是一个页面上必不可少的功能,学习一个新的东西,当然就要学习,如何用新的东西,用它的方法去实现以前的东西啦.今天呢,我就在这里介绍一个试用react-addons-css-transition ...
- 在React中使用Redux
这是Webpack+React系列配置过程记录的第六篇.其他内容请参考: 第一篇:使用webpack.babel.react.antdesign配置单页面应用开发环境 第二篇:使用react-rout ...
- React中的路由系统
React中的路由系统 提起路由,首先想到的就是 ASPNET MVC 里面的路由系统--通过事先定义一组路由规则,程序运行时就能自动根据我们输入的URL来返回相对应的页面.前端中的路由与之类似,前端 ...
随机推荐
- Paxos、ZAB、RAFT协议
这三个都是分布式一致性协议,ZAB基于Paxos修改后用于ZOOKEEPER协议,RAFT协议出现在ZAB协议之后,与ZAB差不多,也有很大区别. 1. Paxos 分布式节点分为3种角色, Prop ...
- C++里创建 Trie字典树(中文词典)(三)(联想)
萌新做词典第三篇,做得不好,还请指正,谢谢大佬! 今天把词典的联想做好了,也是比较low的,还改了之前的查询.遍历等代码. Orz 一样地先放上运行结果: test1 ID : char : 件 w ...
- CSS设计模式之三权分立模式篇 ( 转)
转自 海玉的博客 市面上我们常常会看到各种各样的设计模式书籍,Java设计模式.C#设计模式.Ruby设计模式等等.在众多的语言设计模式中我唯独找不到关于CSS设计模式的资料,即使在网上找到类似内容, ...
- 洛谷P1941 飞扬的小鸟(背包 dp)
题意 题目链接 Sol 很显然的dp,设\(f[i][j]\)表示第\(i\)个位置,高度为\(j\)的最小步数 向上转移的时候是完全背包 向下转移判断一下就可以 #include<bits/s ...
- node.js-cancelled because Node.js is unresponsive
今天初学node.js,但是在使用vs code 进行启动调试的时候出现了一个问题 这个报错,一开始我并不知道是什么意思.(而截至我写这个笔记我也还没了解清楚) 大概翻译出来的意思是说 “node.j ...
- 面向对象设计中private,public,protected的访问控制原则及静态代码块的初始化顺序
第一:private, public, protected访问标号的访问范围. private:只能由 1.该类中的函数 2.其友元函数访问 不能被任何其他访问,该 ...
- 新发布 | 微软开源之路最新进展:FreeBSD落地由世纪互联营运的Microsoft Azure
微软和开源,是近几年业界孜孜不倦的讨论话题,微软也在开源之路越走越宽.最近与 FreeBSD 基金更紧密的合作踏出了微软在开源之路上的又一大步. 自2012年开始,微软在 FreeBSD 与其虚拟化平 ...
- Laravel 生成小程序图文海报最佳方案之一
目前已经更新 2.0 版本,支持生成的海报关联Model,支持是否重新生成海报等功能,具体更新请移步 github: laravel-miniprogram-poster 微信小程序官方并未提供分享到 ...
- Struts的学习-eclipse与idea与struts的连接
1.建立一个空白工程(里面是没有文件的). 可以在文件放置找到项目文件夹 2.点击托管项目到码云 (ps:没有码云帐号的自己注册) 3.按快捷键:ctrl+alt+shift+s 呼出项目结构管理器, ...
- adb工具包使用方法
ADB工具包总共有四个文件,两个exe后缀,两个dll后缀.里面还带有fastboot.exe下载后在PC上安装,如安装到D:\adb_tools-2.0目录,确认目录中带有fastboot.exe文 ...