Creating a Timer Component with useEffect Hook in React
Last Updated :
24 Apr, 2025
Timer Component using React along with its useEffect hook will not only display the elapsed time since the component mounts but also allow users to set and manage the countdown timer dynamically. We will harness the power of the useEffect hook to manage side effects and update the timer seamlessly.
Output Preview: Let us have a look at how the final feature will look like.
Output PreviewPrerequisites:
Functionalities of Timer Component:
- Elapsed Time Display: Upon mounting, the Timer Component will display the elapsed time in hours, minutes, and seconds.
- Countdown Timer: Users can set custom countdown durations according to their requirements.
- Dynamic Timer Updates: Leveraging the useEffect hook, the Timer Component will update in real-time, reflecting changes in countdown duration and elapsed time.
- Timer Controls: Users will have control over the timer through intuitive buttons, enabling them to start, pause, reset, and edit the countdown duration seamlessly.
Approach to create Timer Component:
- Component Initialization: We initialize the Timer Component with state variables to manage hours, minutes, seconds, timer activation status, and editing mode.
- Countdown Logic: Utilizing the useEffect hook, we implement the logic to decrement the timer values at regular intervals while the timer is active.
- User Interaction Handling: We implement functions to handle user interactions such as starting, pausing, resetting, and editing the timer duration.
- Styling for Enhanced User Experience: CSS styles are applied to create an aesthetically pleasing and intuitive user interface, enhancing the overall user experience.
- Dynamic Updates: We ensure that the Timer Component dynamically updates in response to user actions, maintaining consistency and responsiveness throughout the countdown process.
Steps to Create the Project:
Step 1: Create a new React project using Create React App.
npx create-react-app timer-app
Step 2: Change the directory:
cd timer-app
Project Structure:
Project StructureThe updated dependencies in package.json file will look like:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
Example: Below is the code example of the Timer Component with useEffect.
JavaScript
// App.js
import React from 'react';
import './App.css';
import Timer from './Timer';
function App() {
return (
<div className="App">
<header className="App-header">
<h1>
Timer App
</h1>
<Timer />
</header>
</div>
);
}
export default App;
JavaScript
// Timer.js
import React, {
useState,
useEffect
} from "react";
import "./Timer.css";
const Timer = () => {
const [hours, setHours] = useState(0);
const [minutes, setMinutes] = useState(5);
const [seconds, setSeconds] = useState(0);
const [isActive, setIsActive] = useState(false);
const [isEditing, setIsEditing] = useState(false);
const [editHours, setEditHours] = useState(0);
const [editMinutes, setEditMinutes] = useState(0);
const [editSeconds, setEditSeconds] = useState(0);
useEffect(() => {
let interval = null;
if (isActive && (hours > 0 ||
minutes > 0 || seconds > 0)) {
interval = setInterval(() => {
if (seconds === 0) {
if (minutes === 0) {
if (hours === 0) {
clearInterval(interval);
setIsActive(false);
} else {
setHours(hours - 1);
setMinutes(59);
setSeconds(59);
}
} else {
setMinutes(minutes - 1);
setSeconds(59);
}
} else {
setSeconds(seconds - 1);
}
}, 1000);
} else {
clearInterval(interval);
}
return () => clearInterval(interval);
}, [isActive, hours, minutes, seconds]);
const toggleTimer = () => {
setIsActive(!isActive);
// Exit editing mode when starting the timer
setIsEditing(false);
};
const resetTimer = () => {
if (!isEditing) {
setHours(editHours);
setMinutes(editMinutes);
setSeconds(editSeconds);
setIsActive(!isActive);
}
setIsActive(false);
};
const handleInputChange = (e) => {
const { name, value } = e.target;
if (name === "hours") {
setEditHours(parseInt(value));
} else if (name === "minutes") {
setEditMinutes(parseInt(value));
} else if (name === "seconds") {
setEditSeconds(parseInt(value));
}
};
const toggleEdit = () => {
if (isEditing) {
setHours(editHours);
setMinutes(editMinutes);
setSeconds(editSeconds);
}
setIsEditing(!isEditing);
};
return (
<div className="timer-container">
{
isEditing ? (
<div className="editing-container">
<div className="input-group">
<label>HH:</label>
<input
type="number"
name="hours"
value={editHours}
onChange={handleInputChange}
min="0"
/>
</div>
<div className="input-group">
<label>MM:</label>
<input
type="number"
name="minutes"
value={editMinutes}
onChange={handleInputChange}
min="0"
max="59"
/>
</div>
<div className="input-group">
<label>SS:</label>
<input
type="number"
name="seconds"
value={editSeconds}
onChange={handleInputChange}
min="0"
max="59"
/>
</div>
<button className="start-btn"
onClick={toggleEdit}>
Start Timer
</button>
</div>
) : (
<div>
<div className="timer-display">
<span>
{
hours.toString()
.padStart(2, "0")
}:
</span>
<span>
{
minutes.toString()
.padStart(2, "0")
}:
</span>
<span>
{
seconds.toString()
.padStart(2, "0")
}
</span>
</div>
<div className="timer-controls">
<button onClick={toggleTimer}>
{
isActive ?
"Pause" :
"Start"
}
</button>
<button onClick={resetTimer}>
Reset
</button>
<button onClick={toggleEdit}>
Edit
</button>
</div>
</div>
)}
</div>
);
};
export default Timer;
CSS
/* App.css */
.App {
text-align: center;
}
.App-header {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
background: #03001e;
/* fallback for old browsers */
background:
-webkit-linear-gradient(to right, #fdeff9, #ec38bc, #7303c0, #03001e);
/* Chrome 10-25, Safari 5.1-6 */
background:
linear-gradient(to right, #fdeff9, #ec38bc, #7303c0, #03001e);
/*
W3C, IE 10+/ Edge, Firefox 16+,
Chrome 26+, Opera 12+, Safari 7+
*/
}
CSS
/* Timer.css */
.timer-container {
text-align: center;
}
.timer-display {
font-size: 3rem;
font-weight: bold;
margin-bottom: 1rem;
}
.timer-controls button {
margin: 0 0.5rem;
padding: 0.5rem 1rem;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
background-color: #fff;
color: #007bff;
border: none;
border-radius: 5px;
}
.timer-controls button:hover {
background-color: #0056b3;
color: #fff;
}
.editing-container {
display: flex;
flex-direction: column;
align-items: start;
justify-content: flex-start;
}
.input-group {
margin-bottom: 1rem;
display: flex;
flex-direction: row;
align-items: start;
justify-content: flex-start;
width: 10rem;
}
.input-group label {
margin-right: 0.5rem;
}
input[type="number"] {
padding: 0.5rem;
font-size: 1rem;
border: 1px solid #ccc;
border-radius: 5px;
width: 100%;
}
.start-btn {
background-color: #fff;
color: #28a745;
border: none;
border-radius: 5px;
padding: 0.5rem 1rem;
cursor: pointer;
width: 100%;
}
.start-btn:hover {
background-color: #218838;
color: #fff;
}
Step to run the App:
npm start
Output: Open your web browser and go to http://localhost:3000 to view the Timer App.
ReactJS Timer App Output
Similar Reads
How to create a Speed Dial Component in ReactJS ?
The Material-UI Lab hosts new and exciting components that arenât fully ready for the core library. A Speed Dial component is like a dialog with multiple floating action buttons. It can be used to make any primary actions like share, copy, print, etc. more accessible and make the user experience bet
3 min read
How To Call Loading Function With React useEffect?
The useEffect runs by default after every render of the component. When placing useEffect in our component we tell React that we want to run the callback as an effect. React will run the effect after rendering and after performing the DOM updates. If we pass only a callback, the callback will run af
2 min read
How to create a rating component in ReactJS ?
Creating a rating component in React application allows user to register their review and rate the items using clickable stars. Using a custom rating component enhances the UI and experience of users.Prerequisite:Basic knowledge of npm or yarn.styled-components.Basic Knowledge of useState React hook
3 min read
How to simulate componentDidMount with useEffect?
componentDidMount is a lifecycle method that runs after a component has been mounted or rendered to the DOM. It's often used for tasks like fetching data from an API or setting up event listeners. Simulating componentDidMount with useEffect:In functional components, you can achieve similar behavior
2 min read
Create a Modal Component using React Hooks
In this article, we are going to build a modal component using React Hooks. The modal is going to be a user register form modal that will appear on a button click. The modal will utilize the useState hook for its state management. Output Preview: Let us have a look at how the final output will look
4 min read
How to use useMemo Hook in a Functional Component in React ?
In React development, optimizing performance is crucial for delivering responsive and fast user experiences. One way to achieve this is by using the `useMemo` hook. In this article, we'll explore what `useMemo` is, why it's beneficial, and how to use it effectively in functional components. Table of
3 min read
How to create Class Component in React?
JavaScript syntax extension permits HTML-like code within JavaScript files, commonly used in React for defining component structure. It simplifies DOM element manipulation by closely resembling HTML syntax. JSX facilitates the creation of reusable UI building blocks, defined as JavaScript functions
2 min read
How to create components in ReactJS ?
Components in React JS is are the core of building React applications. Components are the building blocks that contains UI elements and logic, making the development process easier and reusable. In this article we will see how we can create components in React JS. Table of Content React Functional C
3 min read
How to create a Functional Component in React?
To create a functional component in React, you define a JavaScript function that returns JSX. These components are stateless and rely on props for data input. Functional components are concise, easy to read, and can utilize React Hooks for managing state and side effects, making them a fundamental b
2 min read
How do you use multiple useEffect in a component?
useEffect is a hook used to perform side effects in function components. If you need to use multiple useEffect hooks in a single component, you can simply place them one after the other within your component function. Key Points for Using Multiple useEffect Hooks:Separation of Concerns: Each useEffe
2 min read