The useRef() hook in React!
Tags: react, javascript, tutorial
Published: 2021-12-16 15:10:24

Hey **fellow creators**

The *useRef()* hook is a way to select elements with React. You could use the usual *document.querySelector* method, however it's not optimised since it'll look through the entire DOM. Whereas if you use this hook, it'll only look in your component!
 
If you prefer to watch the video **version**, it's right here :

{%youtube bW_YeN48WmI%}

##1. Let's look at a real example.
Let's imagine you have a form:
```react
import "./App.css";

function App(){
	return (
		<div className="app">
			<form>
				<label htmlFor="name">Name</label>
				<input type="text" id="name" />

				<label htmlFor="email">Email</label>
				<input type="text" id="email" />

				<button>Submit</button>
			</form>
		</div>
	)
}

export default App;
```
&nbsp;
In order to use the *useRef()* hook, let's import it:
```react
import {useRef} from "react";
```
&nbsp;
Now, let's create some references, by giving it a name:
```react
import {useRef} from "react";
import "./App.css";

function App(){

	const nameRef= useRef();

	return (
		<div className="app">
			<form>
				<label htmlFor="name">Name</label>
				<input type="text" id="name" />

				<label htmlFor="email">Email</label>
				<input type="text" id="email" />

				<button>Submit</button>
			</form>
		</div>
	)
}

export default App;
```
&nbsp;
Now you can just select an element that you want to add inside that ref with the ref attribute. For example, let's add it to the first input:
```react
return (
		<div className="app">
			<form>
				<label htmlFor="name">Name</label>
				<input ref={nameRef} type="text" id="name" />

				<label htmlFor="email">Email</label>
				<input type="text" id="email" />

				<button>Submit</button>
			</form>
		</div>
	)
```

If you log it, it will simply show an object with a property *current* as *undefined.* However, what we want is the value of the *current* property. 

Since the component is executed first, we need to use the hook *useEffect()* to see the value of our ref.
It's because useEffect callback function is triggered **after** the creation of the component.

```react
import {useRef, useEffect} from "react";
import "./App.css";

function App(){

	const nameRef= useRef();

	console.log(nameRef)

	useEffect(() => {
		console.log(nameRef); // your ref obj
	}, [])

	return (
		<div className="app">
			<form>
				<label htmlFor="name">Name</label>
				<input ref={nameRef} type="text" id="name" />

				<label htmlFor="email">Email</label>
				<input type="text" id="email" />

				<button>Submit</button>
			</form>
		</div>
	)
}

export default App;
```

You need to feed the *useEffect()* hook with an arrow function and an empty array, that is the dependency array, it means that useEffect will only be triggered once, after the creation of that component. 


##2. All right, now create a ref for the second input.

```react
import {useRef, useEffect} from "react";
import "./App.css";

function App(){

	const nameRef= useRef();
	const mailRef = useRef()

	console.log(nameRef)

	useEffect(() => {
		console.log(nameRef);
	}, [])

	return (
		<div className="app">
			<form>
				<label htmlFor="name">Name</label>
				<input ref={nameRef} type="text" id="name" />

				<label htmlFor="email">Email</label>
				<input ref={mailRef} type="text" id="email" />

				<button>Submit</button>
			</form>
		</div>
	)
}

export default App;
```
&nbsp;
Usually we use Ref with an onSubmit method:
```react
useEffect(() => {
		console.log(nameRef);
	}, [])

	const HandleSubmit = e => {
		e.preventDefault()
		console.log(nameRef.current.value);
		console.log(mailRef.current.value);
	}

	return (
		<div className="app">
			<form onSubmit={handleSubmit}>
				<label htmlFor="name">Name</label>
				<input ref={nameRef} type="text" id="name" />

				<label htmlFor="email">Email</label>
				<input ref={mailRef} type="text" id="email" />

				<button>Submit</button>
			</form>
		</div>
	)
```

You can add a *console.log()* if you want to use what is inside your inputs, for example for an API call.

Now, whenever you write inside the inputs and submit the form, the values show up in the console.

##3. The multi-ref.
How can you select multiple references if you have too many?


Start a ref with an empty array:

```react
import {useRef, useEffect} from "react";
import "./App.css";

function App(){

	const inputs = useRef([]);

	const HandleSubmit = e => {
		e.preventDefault()
		console.log(inputs.current);
	}

	return (
		<div className="app">
			<form onSubmit={handleSubmit}>
				...
			</form>
		</div>
	)
}

export default App;
```


Then, create a method that will check if the element is not undefined and if it's not already inside the array, then you'll push it inside of the array:

```react
const addInputs = el => {
		if(el && !inputs.current.includes(el)){
			inputs.current.push(el)
		}
	}

```


Add that method to each of your inputs:

```react
return (
		<div className="app">
			<form onSubmit={handleSubmit}>
				<label htmlFor="name">Name</label>
				<input ref={addInputs} type="text" id="name" />

				<label htmlFor="email">Email</label>
				<input ref={addInputs} type="text" id="email" />

				<button>Submit</button>
			</form>
		</div>
	)
```

Well done! You now know how to use the *hook *useRef()** to select your elements!

Check my youtube channel : https://www.youtube.com/c/TheWebSchool

Come and take a look at my **Youtube channel**: https://www.youtube.com/c/Learntocreate/videos

*See you soon!*

Enzo.