2
\$\begingroup\$

I am writing a simple count down timer in React:

index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import bootstrap from "bootstrap/dist/css/bootstrap.css";
import App from "./App";
ReactDOM.render(
 <React.StrictMode>
 <App />
 </React.StrictMode>,
 document.getElementById("root")
);

App.js:

import React, { useEffect, useState } from "react";
const App = () => {
 const oneSec = 1000;
 const [secCount, setSecCount] = useState(60);
 const [minCount, setMinCount] = useState(60);
 const [hrCount, setHrCount] = useState(24);
 useEffect(() => {
 const timer; //<= here is my problem.
 if (secCount > 0) {
 timer = setInterval(() => {
 setSecCount(secCount - 1);
 }, oneSec);
 }
 if (secCount === 0 && minCount > 0) {
 timer = setInterval(() => {
 setSecCount(60);
 }, oneSec);
 }
 return () => clearInterval(timer);
 }, [secCount]);
 useEffect(() => {
 const timer =
 minCount > 0 &&
 setInterval(() => {
 setMinCount(minCount - 1);
 }, 60 * oneSec);
 return () => clearInterval(timer);
 }, [minCount]);
 return (
 <div>
 {minCount}:{secCount}
 </div>
 );
};
export default App;

I am having a hard time with my useEffect hooks. The first useEffect hook is supposed to update the second field, the logic is simply:

  • if secCount is bigger than 0, continue to countdown every second
  • if secCount is zero and minCount is bigger than 0, reset secCount to 60 and continue to countdown.

But since there are two branches in my first useEffect hook, I need to declare the timer variable and reassign it later. Can I get away with declaring it as let timer? A const variable does not allow me to change its value.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Apr 23, 2020 at 9:23
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Yes, you can. Also, instead of declaring it twice inside useEffect, declare timer outside the effect hook and re-assign inside useEffect when needed \$\endgroup\$ Commented Apr 23, 2020 at 13:56

1 Answer 1

3
\$\begingroup\$

let vs const is fundamentally an ES6+ issue:

  • const
    Creates a constant whose scope can be either global or local to the block in which it is declared. An initializer for a constant is required. You must specify its value in the same statement in which it's declared.
// wrong
const timer;
// Uncaught SyntaxError: Missing initializer in const declaration
// right
const timer = 60;
function do_something() {
 console.log(bar); // undefined
 console.log(foo); // ReferenceError
 var bar = 1;
 let foo = 2;
};

With that said, change the declaration to let timer;

// Within the first `useEffect`
useEffect(() => {
 let timer; // change this
 if (secCount > 0) {
 timer = setInterval(() => {setSecCount(secCount - 1)}, oneSec);
 }
 if (secCount === 0 && minCount > 0) {
 timer = setInterval(() => {setSecCount(60)}, oneSec);
 }
 return () => clearInterval(timer);
 }, [secCount]);
```
answered Apr 27, 2020 at 17:56
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.