3

I am creating a game which user can tap a button as much as they can in a range of time.

I have use react-countdown to create Timer. But when I tap to a button, timer is auto reset.

Here my code.

import React, { useState } from "react"
import Countdown from 'react-countdown';

function App() {

  const [name, setName] = useState("")
  const [isLogin, setIsLogin] = useState(false)
  const [counter, setCounter] = useState(0)

  const submitName = () => {
    setIsLogin(true)
  }

  const updateCounter = () => {
    console.log(counter)
    setCounter(counter + 1)
  }

  return (
    <div>
      {!isLogin ? (
        <div>
          <input
            style={{ width: 300, height: 30 }}
            placeholder="Input name here"
            value={name}
            onChange={e => setName(e.target.value)}
          />
          <button
            style={{ width: 50, height: 20, background: "red" }}
            onClick={() => submitName()}
          >Go</button>
        </div>
      ) : (
          <div
            style={{ width: "100vw", height: "100vh", background: "yellow" }}>
            <Countdown date={Date.now() + 100000} />
            <h1>{name}</h1>
            <h3>Click counter: {counter} </h3>
            <button
              style={{
                width: 100,
                height: 50,
                background: "red",
                border: "none",
                borderRadius: 25,
                color: "white",
                cursor: "pointer"
              }}
              onClick={() => updateCounter()}>Click here!</button>
          </div>
        )
      }
    </div>
  );
}

export default App;

The problem is when I tap the button, setCounter(counter + 1) is running and rerender the page. That made the Counter reset. I know why it have issue but I cannot fix it.

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
  • Obviously, you could create the component, which would handle the clicking and update state locally. Thus, only component with counter will be re-rendered. Check out: https://codesandbox.io/s/nostalgic-zhukovsky-y8w3n?file=/src/App.js – Konstantin Samarin Feb 08 '21 at 15:48

2 Answers2

4

You need to memoize the Countdown component:

const CountdownWrapper = () => <Countdown date={Date.now() + 100000} />;
const MemoCountdown = React.memo(CountdownWrapper);

// usage
<MemoCountdown/>

Beforehand, on every render Date.now() gets a new value which resets the timer.

Edit Countdown reset

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
  • Thanks for your support. Another question, how can I use setTimeout instead of react-countdown? – Son Ha Nguyen Feb 08 '21 at 16:22
  • Its the most searched question in SO and in Google, try looking for it, https://stackoverflow.com/questions/40885923/countdown-timer-in-react – Dennis Vash Feb 08 '21 at 16:37
0
import React from 'react';

const time = React.useMemo(() => {
    return Date.now() + 120 * 1000;
}, []);
Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – ethry Oct 06 '22 at 20:13
  • While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. – nima Oct 30 '22 at 07:39