简体   繁体   English

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

[英]How can I remote control react-compound-timer?

I'm working on a kiosk system.我正在研究一个自助服务终端系统。 I have a nodejs server that is pushing the data to be displayed to a react client using server side events.我有一个 nodejs 服务器,它使用服务器端事件将要显示的数据推送到反应客户端。 The react client is only used to display stuff and is not interactive. react 客户端仅用于显示内容,不具有交互性。 I am using react-compound-timer for a countdown.我正在使用react-compound-timer进行倒计时。 I want to set the time, start and pause the timer the client is showing using events generated by the server but I am having trouble finding the right approach to do so.我想使用服务器生成的事件设置时间、启动和暂停客户端显示的计时器,但我无法找到正确的方法来执行此操作。

After some attempts I succeeded in starting and stopping the timer.经过一些尝试,我成功地启动和停止了计时器。 See function remoteControlTimer .请参阅函数remoteControlTimer But I am pretty sure that this is not the intended way of doing it since I am also getting a warning:但我很确定这不是预期的方式,因为我也收到警告:

"Warning: Cannot update during an existing state transition (such as within render ). Render methods should be a pure function of props and state." “警告:无法在现有状态转换期间更新(例如在render内)。Render 方法应该是 props 和 state 的纯函数。”

Also, setting the time has proven to be more difficult.此外,事实证明,设置时间更加困难。 See the comment line in the function remoteControlTimer.请参阅函数 remoteControlTimer 中的注释行。 In my attempt the time is set, but the times is stuck on the set time and does not count backwards anymore.在我的尝试中,时间已设定,但时间停留在设定的时间并且不再向后计数。

I also tried setting a dfferent time in the initialisation block based on what is set in the props, but that does not work, the value is ignored.我还尝试根据道具中设置的内容在初始化块中设置不同的时间,但这不起作用,该值被忽略。

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>
    )
}

As you can guess, I am pretty new to nodejs as well as react.你可以猜到,我对 nodejs 和 react 都很陌生。 Any help is very much appreciated.很感谢任何形式的帮助。

based on your example and the documentation on react-compound-timer, I believe there are two mistakes that may help you move forward.根据您的示例和关于 react-compound-timer 的文档,我相信有两个错误可以帮助您前进。

The first is the arguments to the function inside the Timer component.第一个是 Timer 组件内函数的参数。 According to the documentation you can see from the Controls example, the props they use are: start, resume, pause, stop, reset, timerState.根据您可以从 Controls 示例中看到的文档,它们使用的道具是:start、resume、pause、stop、reset、timerState。 Instead of timerState, you have: getTimerState, getTime, and setTime.您有:getTimerState、getTime 和 setTime,而不是 timerState。 I'm not familiar with the timer component you are using, so I could be mistaken.我不熟悉您正在使用的计时器组件,所以我可能会弄错。

The second thing I see is the call to remoteControlTimer.我看到的第二件事是对 remoteControlTimer 的调用。 This function doesn't return anything, so there you don't need to put it in curly brackets.这个函数不返回任何东西,所以你不需要把它放在大括号中。 Instead, you can convert the implicit-return arrow function into function-body arrow function, where the first line makes the function call for you and the second would return the JSX you would like to render.相反,您可以将隐式返回箭头函数转换为函数体箭头函数,其中第一行为您调用函数,第二行将返回您想要呈现的 JSX。

I'm not fully clear on what you're trying to achieve, so this is the best I can do with what you've provided.我不完全清楚你想要达到的目标,所以这是我能用你提供的东西做的最好的事情。 Hope this helps!希望这可以帮助!

eg例如

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>
    )
}

Here is the approch I took, using React Hook.这是我采用的方法,使用 React Hook。 You can use useRef() to call them on your own functions您可以使用useRef()在您自己的函数上调用它们

example:例子:

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>
      )}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM