An Interest In:
Web News this Week
- April 26, 2024
- April 25, 2024
- April 24, 2024
- April 23, 2024
- April 22, 2024
- April 21, 2024
- April 20, 2024
Build a Timer with React Hooks
In this tutorial, you will learn how to build a timer using react hooks. React hooks is the new way of building react apps and its been available since v16.8.0. More about hooks here
Hooks let you always use functions instead of having to constantly switch between functions, classes, higher-order components, and render props. - Dan Abramov
Let's dive right in.
Requirements
For this tutorial, you'd need basic understanding of React and Javascript.
Getting started
You can use create-react-app to quickly scaffold a new react app.
npx create-react-app react-timer
Building the timer
Create a Timer.js
component and style.css
file.
import React from 'react';import './style';const Timer = () => { return ( <div className="container"> <div className="time"> <span className="minute">00</span> <span>:</span> <span className="second">00</span> </div> <div className="buttons"> <button onClick={() => null} className="start">Start</button> <button onClick={() => null} className="reset">Reset</button> </div> </div> )}export default Timer;
This is the barebones Timer component. It has the minute and second values which are hardcoded for now, and two buttons to start and reset the timer.
Styles
Add these styles to style.css
file to make the Timer visually appealing.
.container { width: 600px; margin: 0 auto; display: grid; place-items: center; margin-top: 5rem; background: rgb(66,4,53); background: linear-gradient(90deg, rgba(66,4,53,1) 0%, rgba(81,22,111,1) 35%, rgba(12,29,84,1) 100%); padding: 3rem 5rem; border-radius: 10px;}.time { font-size: 8rem; margin-bottom: 1rem; color: white;}.buttons button { padding: 0.8rem 2rem; border: none; margin-left: 0.2rem; font-size: 1rem; cursor: pointer; border-radius: 5px; font-weight: bold; transition: all 300ms ease-in-out; transform: translateY(0);}.buttons button:hover { transform: translateY(-2px);}.start { background: #3ed927; color: white;}.pause { background: #e4e446;}.reset { background: #fd7171; color: white;}
Managing State with useState
We make our Timer a stateful component by using useState
.
import React, { useState } from 'react';const [second, setSecond] = useState('00');const [minute, setMinute] = useState('00');const [isActive, setIsActive] = useState(false);const [counter, setCounter] = useState(0);const Timer = () => { return ( <div className="container"> <div className="time"> <span className="minute">{minute}</span> <span>:</span> <span className="second">{second}</span> </div> <div className="buttons"> <button onClick={() => setActive(true)} className="start">Start</button> <button onClick={() => null} className="reset">Reset</button> </div> </div> )}
We now have the second
, minute
, isActive
and counter
values in state. isActive
will be used to toggle the active and inactive states of the timer. We start the timer by adding an onClick handler to the start button which sets the isActive
state to true.
Adding effects with useEffect
To trigger the timer which is a side effect, we need to use useEffect
.
import React, { useState, useEffect } from 'react';const [second, setSecond] = useState('00');const [minute, setMinute] = useState('00');const [isActive, setIsActive] = useState(false);const [counter, setCounter] = useState(0);const Timer = () => { useEffect(() => { let intervalId; if (isActive) { intervalId = setInterval(() => { const secondCounter = counter % 60; const minuteCounter = Math.floor(counter / 60); const computedSecond = String(secondCounter).length === 1 ? `0${secondCounter}`: secondCounter; const computedMinute = String(minuteCounter).length === 1 ? `0${minuteCounter}`: minuteCounter; setSecond(computedSecond); setMinute(computedMinute); setCounter(counter => counter + 1); }, 1000) } return () => clearInterval(intervalId); }, [isActive, counter]) return ( <div className="container"> <div className="time"> <span className="minute">{minute}</span> <span>:</span> <span className="second">{second}</span> </div> <div className="buttons"> <button onClick={() => setIsActive(!isActive)} className="start"> {isActive ? "Pause": "Start"} </button> <button onClick={() => null} className="reset">Reset</button> </div> </div> )}
Lets break down what's going on in the useEffect
.
- Toggle the start button value(Start or Pause) based on
isActive
state. - We only run the
setInterval
function ifisActive
is true. secondCounter
is calculated by getting the remainder of counter divided by 60 - using the modulo operator (%).minuteCounter
is calculated by dividing the counter by 60 and rounding it down usingMath.floor
.- We append an extra zero to the second and minute values so that we always have 2 digits.
- We update the
second
andminute
states using thecomputedMinute
andcomputedSecond
values. count
is also increased by 1 every second the effect runs.- We return a cleanup function to clear the interval when the effect stops running.
- Lastly, we add the
isActive
andcounter
state to the dependency array. This ensures that the effect only runs when either of them changes.
To stop the timer and reset all state values, we add a stopTimer
function which runs when the reset button is clicked.
import React, { useState, useEffect } from 'react'; // state values are here ...... // useEffect runs here .......const Timer = () => { function stopTimer() { setIsActive(false); setCounter(0); setSecond('00'); setMinute('00') } return ( <div className="container"> <div className="time"> <span className="minute">{minute}</span> <span>:</span> <span className="second">{second}</span> </div> <div className="buttons"> <button onClick={() => setIsActive(!isActive)} className="start"> {isActive ? "Pause": "Start"} </button> <button onClick={stopTimer} className="reset">Reset</button> </div> </div> )}
Live app
Original Link: https://dev.to/emmaadesile/build-a-timer-using-react-hooks-3he2
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To