# A Look At React Hooks: useRef

Welcome to [A Look at React Hooks](https://hashnode.com/series/a-look-at-react-hooks-ckicwasfb00a0t0s15sv9bd6q), a beginner-friendly series on React Hooks. In this article, let's look at the `useRef` Hook.

## What is useRef?
`useRef` returns a mutable object with a single property: `current`, that stores the value of the reference element like so:
```
{ current: ReactElementReference }
```
This stored value persists for the **entire lifetime of the component** and will not re-render the component when the value of `current` is mutated.

Hence, this Hook is useful for storing and updating values that are frequently changing because as mentioned in [this article](https://lo-victoria.com/a-look-at-react-hooks-usestate), the `useState` Hook will trigger a re-render on every state update.

Another reason to use this Hook is when you want to imperatively access a DOM element, and altering its state according to what you want it to do. 

To do this, simply add a `ref` attribute in an element created in its render method. For example, `<div ref={myRef}>`. Now, React is able to access this `<div>`  element directly. We will see how this Hook allows React to access the element soon.

In short, use `useRef` when you want to:
1. Store and update mutable information without triggering re-renders all the time
2. Access variables that are persisted across re-renders
3. Imperatively access DOM nodes via refs to perform some functions

## Initialization
First, import the Hook:
```
import React, { useRef } from 'react';
```
Then, declare and initialize the ref:
```javascript
// initializes the current property of the ref aka 
// inputElement.current = null
const inputElement = useRef(null);
// useRef now returns {current: null}
```
## Simple Example
Now, we can use this Hook to access the input element imperatively by having the `ref` attribute of `<input>` equal to `inputElement`:
```javascript
  return (
    <div>
       <!--passing in inputElement as ref-->
      <input ref={inputElement} type="text" />
      <button onClick={onButtonClick}>SUBMIT</button>
    </div>
  );
```
Accessing an element this way is how we can access methods that we normally can do with `document.getElementById()` in vanilla JavaScript. Like `focus()` or `.value`. Let's write the `onButtonClick` function in our above example.

```
const onButtonClick = () => {
    inputElement.current.focus(); // focuses the ref element
    console.log(inputElement.current.value) // prints the value of the ref
  };
```
And that's the basics of `useRef`! Pretty straightforward, isn't it? So let's take it further by learning a closely related Hook: `useImperativeHandle`.

## useImperativeHandle
A Hook that is often used with `useRef` is `useImperativeHandle`. Basically, it hides the DOM node reference from its parent component and exposes only the properties you want.

The Hook accepts a `ref` object and a handler function. This handler function specifies the properties of the `ref` that its parent component can access. So the parent of the `ref` will not be able to access the entire `ref` object; just the ones in the handler function. The Hook must be used with `forwardRef` so that the `ref` attribute can be passed to another component. Let's look at an example.

> Read more about forwardRefs [here](https://reactjs.org/docs/forwarding-refs.html)

### Example
Here's a simple example of the `useImperativeHandle` Hook in action. Code is taken from React Docs. Let's understand it step-by-step.
```javascript
//FancyInput component
function FancyInput(props, ref) {
  //initialize useRef
  const inputRef = useRef();

  //initialize useImperativeHandle
  //it accepts ref as 1st arg and the handler function
  //returns the inputRef.current.focus() method
  //any parent component will only be able to access
  //focus property, not the inputRef itself
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));

  //sets the input element as the ref
  return <input ref={inputRef} ... />;
}

//use forwardRef to pass the ref attribute
FancyInput = forwardRef(FancyInput);
```
In the code above, we have a FancyInput component and its `<input>` element as its `ref` object. The `useImperativeHandle` Hook then takes this `ref` object as its 1st argument and returns an object in its handler function as its 2nd argument. This object includes `focus()` method of the `current` property of the `ref`.

Let's say `<App/>` is the parent of FancyInput. It will only be able to access `inputRef.current.focus()` instead of the input element itself as seen in the image below. Whereas FancyInput itself gets access to the entire `inputRef`.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1613205171897/1hiPDdnCj.png)

## Conclusion
And that's the gist of this Hook! Thanks for reading this article. I hope it was helpful for React beginners. Please feel free to ask questions in the comments below. Ultimately, practising and building projects with this Hook will help anyone to pick it up faster. 

The next Hook in this series will be: `useReducer`. Stay tuned and cheers!

-----
### Resources
- https://reactjs.org/docs/hooks-reference.html
- https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables
- https://react-hooks-cheatsheet.com/useRef
- https://reactjs.org/docs/react-api.html#reactforwardref
- Image from: https://blog.logrocket.com/react-reference-guide-hooks-api/#useimperativehandle
