如何远程控制复合计时器?

时间:2019-06-28 18:02:36

标签: javascript reactjs

我正在使用信息亭系统。我有一个nodejs服务器,它使用服务器端事件将要显示的数据推送到React客户端。 react客户端仅用于显示内容,并且不是交互式的。我正在使用react-compound-timer进行倒计时。我想使用服务器生成的事件来设置时间,启动和暂停客户端正在显示的计时器,但是我在寻找正确的方法上遇到困难。

经过几次尝试,我成功启动和停止了计时器。请参见功能 remoteControlTimer 。但是我很确定这不是预期的做法,因为我也收到警告:

“警告:无法在现有状态转换过程中(例如,在render之内进行更新。渲染方法应仅是props和state的函数。”

此外,事实证明,设定时间更加困难。请参见函数remoteControlTimer中的注释行。我尝试设置时间,但是时间停留在设置的时间上,不再倒退。

我还尝试根据道具中设置的内容在初始化块中设置一个不同的时间,但这不起作用,该值将被忽略。

function remoteControlTimer(start, stop, data, setTime) {
    // setTime(data.value)
    if (data.state == StopWatchState.PLAY) {
        console.debug('play')
        start()
    } else {
        console.debug('stop')
        stop()
    }
}

function Stopwatch(props) {
    return (
        <Timer 
            initialTime={props.data.value} 
            direction="backward" 
            startImmediately={false}
            timeToUpdate='10' >
            {({start, resume, pause, stop, reset, getTimerState, getTime, setTime}) => (
                <React.Fragment>
                    <div>
                        <Timer.Minutes />:
                        <Timer.Seconds />:
                        <Timer.Milliseconds />
                    </div>
                    {remoteControlTimer(start, stop, props.data, setTime)}
                </React.Fragment>
            )}
        </Timer>
    )
}

您可以猜到,我对Node.js还是反应很新。非常感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

根据您的示例和react-compound-timer的文档,我相信有两个错误可以帮助您前进。

第一个是Timer组件内部函数的参数。根据{{​​3}},您可以从Controls示例中看到,它们使用的道具是:启动,恢复,暂停,停止,重置,timerState。您可以使用getTimerState,getTime和setTime来代替timerState。我不熟悉您使用的计时器组件,所以我可能会误会。

我看到的第二件事是对remoteControlTimer的调用。此函数不返回任何内容,因此您无需将其放在大括号中。相反,您可以将隐式返回箭头函数转换为函数体箭头函数,其中第一行为您调用该函数,第二行将返回您要呈现的JSX。

对于您要实现的目标,我还不太清楚,所以这是我可以用您所提供的最好的方法。希望这会有所帮助!

例如

function Stopwatch(props) {
    return (
        <Timer 
            initialTime={props.data.value} 
            direction="backward" 
            startImmediately={false}
            timeToUpdate='10' >
            {({start, resume, pause, stop, reset, timerState}) => {
              remoteControlTimer(start, stop, props.data)
              return (
                    <div>
                        <Timer.Minutes />:
                        <Timer.Seconds />:
                        <Timer.Milliseconds />
                    </div>
            )}}
        </Timer>
    )
}

答案 1 :(得分:0)

这是我使用React Hook采取的方法。 您可以使用 useRef()在自己的函数上调用它们

示例:

import React, { useRef, useEffect, useState } from 'react'
import Timer from "react-compound-timer";


const TestTimer = () => {

  const startTimeFunc = useRef()

  function handleStartTime() {
    startTimeFunc.current.start()
  }

return (<Timer
        initialTime={1500000}
        direction="backward"
        startImmediately={false}
        onStart={() => console.log("call back on start")}
      >
        // assign control to startTimeFunc
        {(control) => {
          startTimeFunc.current = control

          return (
            <React.Fragment>
                <div>
                  {' Study time: '}
                  <Timer.Minutes /> minutes {' '}
                  <Timer.Seconds /> seconds
                </div>
              <br />
              <div>
                <button className="studyButton" onClick={handleStartTime}>Start studying</button> {' '}
              </div>
            </React.Fragment>
          )
        }}
        </Timer>
      )}