# I want the reference !

When developing React applications, it is common to create reusable components that can be used in multiple places by passing appropriate props to achieve the desired behavior. However, there may be situations where you want to control the state of a component from outside of its scope, such as when you need to manage the child component's state from the parent component.

This blog explains how to control the state of the child component using one of the hooks(secret will be revealed soon :)) ) offered by React.

**We are going to build a Timer component that can be used across the project!.**

And it should have a start, stop and reset functionality

let's create our timer component,

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689524485310/7b4e2e98-be15-49c4-a569-e13824880b2f.png align="center")

**Let's breakdown the timer**

**currentTime**: we are storing the initial state of the timer in the currentTime variable

In our example, the **timer** and **setTimer** variables are created using the **useState** hook, which allows us to initialize and manage the state in our **Timer** component. The **useState** hook returns an array with two elements: the current state value (**timer**) and a function to update the state (**setTimer**). which is destructed and stored respectively.

The **currentTime** variable is passed as the initial state value to **useState**. It holds the initial state that will be assigned to the **timer** variable when the component is first rendered. The **setTimer** function can later be used to update the value of the **timer** as needed.

Now, the state is created, it's time to update the state using the handlers

We require three handlers to update the state namely,

**start():** To start the timer,

**stop():** To pause the timer,

**reset():** To reset it to the initial state

so in our example, we have created these handlers and will go through it one-by-one

1\. **start() This method contains the core logic of this timer component, which can be described as follows,**

We create a **setInterval** method to implement the timer functionality. The **setInterval** is a web API offered by the browser environment that allows us to repeatedly execute a callback function at a specified time interval. In this case, we set the callback to be executed every 1000ms, which is equivalent to 1 second

as we created an outline of the timer logic using **setInterval** let's take a closer look at the callback function that is responsible for updating the state based on the logic executed for each second

instead of directly updating the state, we first get the prev state using the **setTimer function,** based on the prev state we update the current state

**let { hours, minutes, seconds} = prev,** this line destructs each property from the previous state and initializes the values respectively

then we check for the **seconds** value **to be equal to 59** if it is then we increment the **minutes** from the **previous(prev)** value **and** override the **seconds** value to **0 t**o keep track of it for the next minutes and so on

then the second if condition that is nested within this block is to check for the minutes whether it has reached **60** because every 60 seconds update every minute, which increases the hours too, if the minutes have reached 60 seconds we override the **minutes** value to **0 and increments the hours to 1** from the **previous(prev) state,**

then we terminate the if condition by returning the new state with the updated value based on the conditions.

**return {hours, minutes, seconds}** ( es6 syntax '[object literals](https://www.geeksforgeeks.org/javascriptes6-object-literal-enhancement/)' )

Before checking whether the seconds have reached 59 or not, we increment the seconds within the callback function for each execution by default returning the state as **{...prev, seconds: prev.seconds+1}** with the previous state using the rest operator.

and we store the created setInterval instance/id in a variable called **myTimerReference** to clear it whenever needed.

2\. **stop()** This method simply clears the interval that is stored in the **myTimerReference** variable, so that the state is not updated as the setInterval which has the state update logic won't be executed because it has been destroyed.

**Note:** here we are not updating the timer to the initial state, because by the next time the **start()** function is executed the new timer reference is created and stored in **myTimerReference** but now it updates the state from **a previous state,** not from the **initial state,** by doing so we achieved the pausing functionality.

3\. **reset()** This method clears the stored interval to stop the timer by calling the **stop()** method and additionally updated the state to the initial state **setTimer(currentTime)** so that by the next time the start method is called the timer starts from **00 : 00 : 00 hours.**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689524413192/d3471d64-785b-4671-ab7c-e29cd8fe5b8c.png align="center")

So, this is how we use our **Timer** component . . .

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689520455163/2c315ba5-5ecd-4c42-ba72-159642d5a93d.gif align="center")

**A new requirement is added,** where the same timer functionality should be implemented using different layouts on different screens, but there should be no change in the layout that was previously created.

ha.... the nightmare for a developer starts ...

so now we go and create a new timer component with the same functionality but with a different layout, but we have already created a **Timer** component that servers the same purpose, but it can't be used as the state is controlled by itself.

but being an skilled developer now we are going to modify the **Timer** component in such a way that the state can be controlled from the parent component.

**so the approach is,**

Now some how we have to give access to the parent component to control the state, **Secret revealed! . . .**

Here we make use of the **useRef()** hook to achieve this

How?

Let's understand this with the modified **Timer** component

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689524328832/597bb1d7-5a9c-416a-ae46-6ab87b389429.png align="center")

if we observe carefully the **Timer** component is exported by wrapping it with a function called **forwardRef(Timer)**

Because the reference from the parent cannot be passed as an property of props to the functional component, so to pass the ref as an props to the child component we wrap the **Timer** component in **forwardRef()** which has been offered by react allows the component accept the ref as an second parameter.

Now we got the **ref** of the parent and we attach that with the div

**&lt;div ref={ref}&gt; . . . &lt;/div&gt;**

but is that enought to do the work ? a big nooo.......

The key thing here is to attach the handlers such as **start, stop, reset** that updates the state to the **ref** as below

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689525313734/9765c921-1b25-4ab5-b736-4ccbd09ba03a.png align="center")

It's time to modify our **App** component

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689525511459/078f270e-79b8-4b1a-bb18-44fd8a42b86c.png align="center")

Here the parent component **App(I)** **want the reference !** of the one of its child component by passing the **timerRef** as an **ref** to the **Timer** component and control the state by using it in the **onClick** of the respective events.

Ha this way we control the **Timer**

**Conclusion**

In addition to using **ref**, it's worth noting that the desired functionality can also be achieved by leveraging the power of **Higher Order Components (HOC)**. By creating a custom HOC and wrapping the component, we can add the necessary logic and functionality. This approach offers flexibility in reusing and composing functionality across multiple components, promoting code reuse and separation of concerns. Therefore, both **ref** and **HOC** are viable options to accomplish the desired behavior, and the choice between them depends on specific project requirements and preferences.

If you believe an example using Higher Order Components (HOC) would be helpful, please let me know in the comments.
