Step by step: React Timer Component Using Hooks
Tags: javascript, react, tutorial, beginners
Published: 2022-03-16 14:12:03

**Today I would like to show you my example of creating a timer.**:stopwatch:

This is what the component looks like (in storybook) :
![storybook example Timer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/co0xedgjuzbuarg5fgxx.gif)

**Programming language:** JavaScript / TypeScript
**Library:** React
**Usage:** timer as a functional component using react-hooks,
**Expectations:** displays the elapsed time while taking the quiz and displays the total time in the last step that is the result of the quiz

![Timer Component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4sourfz5yzcchvq36tgb.png)

I create an arrow function called Timer and pass 3 arguments to it: `isActive`, `seconds`, `setSeconds`. 
- `isActive` is a boolean variable that provides information as to whether the Timer is on (if `isActive` is true, the clock is running)
- `seconds` is a variable of the type `number` that represents the value of the clock counter. The value that initializes this variable is 0 because this timer will begin counting from 0
- `setSeconds` is a function that modifies state which is contained in another component, it expects that passed function to behave like the function returned by hook `useState`


The body of the Timer function contains:
- useEffect in which: 
  - if `isActive` is true, i.e. the clock is on, the JavaScript function `setInterval` will run, which increases the variable seconds by one every 1000 milliseconds - that is every 1 second
  - `setSeconds(prevSeconds => prevSeconds + 1)` means that the previous value is increased by one (0 + 1 = 1, 1 + 1 = 2, 2 + 1 = 3, 3 +1 = 4 ... etc)

I'll pause here to explain why we're using the useEffect Hook.
When looking for information about `useEffect`, you can often encounter the following content: "The Effect Hook lets you perform side effects in function components.". Personally, that doesn't tell me much. So I will share how I understand it. 

Hook `useEffect` is like a combination of `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount`. It is related to the component lifecycle because it starts only when the component is mounted and exits when the component has been unmounted on the page. 

In addition, we use `useEffect` for components whose functionality does not depend on the direct user interaction of the interface. Our sample clock will update itself while active with the passage of time, it does not depend on the interaction of the user using the website, it is not possible to click on it and change it.

Another feature of using `useEffect` is that in addition to starting a timer, it will also handle a timer clean up, which should always happen before the component is unmounted. 

The operation of `useEffect` and its updating can be made dependent on some other data using the dependency table. In this case, in the dependency array, I have put: `isActive` and `setSeconds`. The dependency on `isActive` is that when `isActive` changes to false, the clock should stop counting. The change will run again `useEffect` which on the second execution will start with the `clearInterval` cleaning function, then in the function body the `if(isActive)` condition will be checked again and the function will exit. 

The second dependency `setSeconds` is making sure, that `useEffect` will always use the current version of this function.

For people who like diagrams:blush:- I have prepared my own diagram showing useEffect flow: 

![diagram useEffectflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t6t9l4n87qztpx65bdve.png)

- Finally, Timer returns the Typography component (from the MUI library), which displays the elapsed time.


I display the elapsed time in hh:mm:ss format and use the `formatSeconds` function to get seconds into that format.


![function formatSeconds](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nhzyte248wyy9nspo3h.png)


Finally, you can display a working Timer wherever you want on the page:information_desk_person: 


![all code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nvoon2st62uvi2eg5m7i.png)