码迷,mamicode.com
首页 > 其他好文 > 详细

React中需要多个倒计时的问题

时间:2018-07-21 16:56:15      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:回调函数   component   计时   count   isp   tst   .com   play   ons   

最近有一个需求是做一个闪购列表,列表中每一个商品都有倒计时,如果每一个倒计时都去生成一个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中需要多个倒计时的问题

标签:回调函数   component   计时   count   isp   tst   .com   play   ons   

原文地址:https://www.cnblogs.com/minz/p/9346726.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!