简体   繁体   中英

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. The react client is only used to display stuff and is not interactive. I am using react-compound-timer for a countdown. 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 . 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."

Also, setting the time has proven to be more difficult. See the comment line in the function 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. 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.

The first is the arguments to the function inside the Timer component. According to the documentation you can see from the Controls example, the props they use are: start, resume, pause, stop, reset, timerState. Instead of timerState, you have: getTimerState, getTime, and setTime. 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. 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.

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. You can use useRef() to call them on your own functions

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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