zoukankan      html  css  js  c++  java
  • 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>
            );
        }
    }
    
  • 相关阅读:
    tmux commands
    智能指针类HasPtr
    关于Vector中存放指针的问题
    面向对象的理解
    关系模型 超键 候选键 主键
    数据库的三个范式
    static struct QMetaObject const QwtPlot::staticMetaObjec
    static作用(修饰函数、局部变量、全局变量)
    C++全局变量之extern和static
    QTabWidget 使用小记
  • 原文地址:https://www.cnblogs.com/minz/p/9346726.html
Copyright © 2011-2022 走看看