Here’s an easy way to build a timer using ReactJS.
For this simple app, we will use useEffect
and useState
hooks to initialize and store our app state.
What this timer does?
It’s a simple timer which goes from 0 to ∞.

You click the button to initiate your counter and it goes on forever. To make it a little interesting, we also have a button which will set the timer to the value of 0
on clicking.
First, if you just wish to see the code, here’s it.

// App.js
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [count, setCount] = useState(0);
const [isCounting, setIsCounting] = useState(false);
const startCount = () => {
setInterval(() => {
setCount(count => count + 1);
}, 1000);
setIsCounting(true);
};
const resetCount = () => setCount(0);
const Timer = (count) => (
<>
<p>Count: {count}</p>
<div className="buttons">
<button onClick={resetCount}>Reset</button>
<button onClick={startCount} disabled={isCounting}>
Start
</button>
</div>
</>
);
return (
<div className="App">
<Timer count={count}/>
</div>
);
}
// index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
/* styles.css */
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.App {
font-family: sans-serif;
background-color: #39cccc;
color: #001f3f;
min-height: 340px;
display: flex;
justify-content: center;
align-items: center;
font-size: 2.5em;
flex-direction: column;
}
.buttons {
margin-top: 0.5em;
}
button {
text-transform: uppercase;
margin: 1em;
padding: 1em 2em;
border: none;
border-radius: 5px;
cursor: pointer;
color: #37474f;
border-color: #37474f;
}
button:focus {
border: none;
}
button:hover {
color: white;
background-color: #001f3f;
}
button:disabled {
cursor: not-allowed;
background-color: #37474f;
color: white;
}
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<title>React Timer App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
</body>
</html>
// package.json
{
"name": "react_timer_app",
"version": "0.0.1",
"description": "React Timer App",
"main": "src/index.js",
"dependencies": {
"react": "16.13.1",
"react-dom": "16.13.1",
"react-scripts": "3.4.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
Initializing the counter
In our app, the counter doesn’t start automatically. For that, we have the start
button.
const [count, setCount] = useState(0);
const [isCounting, setIsCounting] = useState(false);
On the top of the App
function, we have initialized two states for count
and isCounting
.
Updating the counter
The start
button has an onClick
handler where we initialize a setInterval
function. This starts the counter and updates the count
‘s value every 1000
ms.
setCount(count => count + 1);
Similar to the Start
button, we have the Reset
button. This changes the count
‘s value to 0
on clicking using the following function.
const resetCount = () => setCount(0);
As you can see, the app structure is pretty simple. You only have a count
state which we are manipulating using React.useState
function.
Leave a Reply