【问题标题】:Countdown Timer function in React-ReduxReact-Redux 中的倒数计时器功能
【发布时间】:2019-10-20 03:20:50
【问题描述】:

所以我在 Symfony 中创建了这个特定的 javascript 函数,遗憾的是,现在我必须在 React-Redux 中重做这一切,将数据从 Symfony 后端发送到 React 应用程序。遗憾的是,我仍然是 React 的初学者,我无法让它发挥作用。

这是我的问题的详细信息: 我有一个列表,显示停在我的停车场的所有汽车,每辆车都有一个日期时间值显示该车何时停放,另一个整数值显示该车将停放多少分钟。

我的函数获取日期时间值,将其转换为 UTC 并将整数值分钟添加到它,所以它给了我汽车必须离开停车场的时间。

然后它生成另一个当前时间值:并执行此功能:结束时间 - 当前时间。

所以我得到了所有汽车的列表,每辆车前面都有倒计时。

正如我所说,现在我必须在 React-Redux 中集成这个功能:

这是我的 PHP 代码: 我会在实体类本身中计算过期时间

    public function getExpiresAt()
    {
      $parkedAt= $this->getParkedAt();
      $expires = clone $parkedAt;
      $expires->modify('+' . $this->getTime() . ' min');

      return $expires->format('U');
    }

之后,我在树枝中创建了一个带有该值的跨度

    <td>
     <span class="timer" data-expires="{{ car.getExpiresAt() }}"></span>
    </td>

并使用此函数创建倒计时:

<script>
    var timers = document.querySelectorAll('.timer')

    function updateTimers () {

      var rightNow = Math.floor((Date.now()/1000)+3600) // in seconds
      timers.forEach(function (timer) {
        var expires = parseInt(timer.dataset.expires) // in seconds

        if (rightNow > expires) {
                    timer.innerText ='expired'

       } else {
          //  console.log('expires',expires,'rightNow',rightNow);
          var seconds = expires - rightNow
          var minutes = Math.floor(seconds/60)
          var hours = Math.floor(minutes/60)
          var days = Math.floor(hours/24)
          seconds = ('0' + String(seconds%60)).slice(-2)
          minutes = ('0' + String(minutes%60)).slice(-2)
          hours = ('0' + String(hours%24)).slice(-2)
          timer.innerText = days + 'd ' + hours + 'h ' + minutes + 'm ' + seconds + 's'

        }

      })

      setTimeout(function () {
        updateTimers()
      }, 100)

    }

    updateTimers()
  </script>

最后这是我的 React 应用程序中的 carList.js:

import React from 'react';
import {Message} from "./Message";
import {Spinner} from "./Spinner";

export class CarList extends React.Component {
    render() {
        const {carList}=this.props;
        console.log(carList);


        if (null === carList){
        return (<Message message="No cars"/>); 
        }

        return (

            <div className="card mb-3 mt-3 shadow-sm">
                { carList.map(car => {
                    return (

                            <div className="card-body border-bottom" key={car.id}>
                                <p className="card-text mb-0">
                                    {car.number}
                                </p>
                                <p className="card-text">
                                    <small className="text-muted">{car.parkedAt}</small>
                                </p>

                                <p>
                                    <span className="timer"></span>
                                </p>
                            </div>

                    );


                })}
            </div>
        )
    }



}

【问题讨论】:

    标签: javascript reactjs api symfony react-redux


    【解决方案1】:

    我可以假设您将在 car.expires 中提供汽车停留时间

    所以,你应该在 reacts 渲染中计算过期倒计时:

    {carList.map(car => {
        return (
            <div className="card-body border-bottom" key={car.id}>
                .....
                <p className="card-text">
                    <small className="text-muted">Experies in: {this.getExirationTime(car.expires)}</small>
                </p>
    
                ....
            </div>
        );
    })}
    

    然后你将在我们的 CarList 类中声明这个 getExirationTime 方法。此外,您还使用两个反应方法(componentDidMount/componentDidUpdate)通过重新渲染此组件来安排 timeres 的下一次更新。

    export class CarList extends React.Component {
        componentDidMount() {
            // Schedule the updates and forcer re-render if we had cars.
            this.timer = setInterval(() => {
                // this.props should be different each time.
                const { carList } = this.props;
    
                if (carList !== null && carList.length) {
                    this.forceUpdate()
                };
            }, 1000)
        }
    
        componentWillUnmount() {
            clearInterval(this.timer);
        }
    
        getExirationTime(expireIn) {
            // modified code from your code
            var right  Now = Math.floor((Date.now()/1000)+3600);
            var expires = parseInt(timer.dataset.expires) // in seconds
    
            if (rightNow > expireIn) {
                return 'expired';
            } else {
                var seconds = expireIn - rightNow
                var minutes = Math.floor(seconds/60)
                var hours = Math.floor(minutes/60)
                var days = Math.floor(hours/24)
                seconds = ('0' + String(seconds%60)).slice(-2)
                minutes = ('0' + String(minutes%60)).slice(-2)
                hours = ('0' + String(hours%24)).slice(-2)
    
                return days + 'd ' + hours + 'h ' + minutes + 'm ' + seconds + 's'
            }
        }
    
        render() {
            const {carList}=this.props;
            console.log(carList);
            ......
    

    仅此而已。如果有汽车,该组件将每秒更新一次。

    【讨论】:

    • 实际上我还没有计算过期时间,我只是将 parkedAt 和 Time 转换为 UTC 然后添加以获得该值
    • 您可以在后端执行此操作,然后直接使用它,或者将此停车时间发送到前端并在 getExirationTime() 中计算该时间,然后将其与 parkedAt 一起传递。 this.getExirationTime(car.parkedAt, car.time);它在你身上。
    • 再次,非常感谢。我算得很好,我有一个小错误,但这主要是因为我没有正确转换到期日期。我现在正在修复它。
    猜你喜欢
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 2012-01-09
    相关资源
    最近更新 更多