Refs and Forward Refs in React.
By: Akhilesh Ojha
Tags: JavaScript, React, React Refs

React Refs are a useful feature that acts as a means to reference a DOM element.

But the question here is why can we not directly manipulate the DOM using normal JavaScript DOM Manipulation?

Here is an example of why normal JS DOM Manipulation won’t be as useful as Refs when it comes to using React.

Suppose you have a component which has multiple input element. Now, what if we want to focus on the second input element or any other input element as soon as we render the component?

What happens when we use normal JS DOM Manipulation?

import React, { Component } from 'react'; export class InputRef extends Component { componentDidMount() {

document.querySelector('input').focus();

} render() {

return (

<div>

<input type="text" />

<input type="text" />

<input type="text" />

</div>

)

} }

export default InputRef;

Here we do indeed focus, but we always focus on the first input element. Simply because document.querySelector selects the first input element it finds in the entire DOM.

This is because document.querySelector is not something that is related to React but is a general DOM Selector.

We can anyway add an id to these inputs and focus according to id, but React offers a better alternative. The Refs.

Refs in Class-Based Components. Old Approach.

Here we pass a function (anonymous arrow function)in the input element which you want to focus on. The argument that we get is a reference to the element on which we place the function and we can use that reference in our function body.

import React, { Component } from 'react'; export class InputRef extends Component { componentDidMount() {

this.inputElRef.focus();

} render() {

return (

<div>

<input type="text" />

<input type="text" ref={(inputElRef) => {this.inputElRef = inputElRef}}/>

<input type="text" />

</div>

)

} }

export default InputRef;`

Here this.inputElRef will store our reference in global property and hence we can access that reference anywhere in our component (in our case componetDidMount()).

Since React-16.3 we now have another way of using Ref and that uses CreateRef.

Here instead of passing a function to Ref, we can directly assign the value that we have using createRef to our input element.

import React, { Component } from 'react'; export class InputRef extends Component { constructor(props) {

super(props);

this.inputElRef = React.createRef();

} componentDidMount() {

this.inputElRef.current.focus();

} render() {

return (

<div>

<input type="text" />

<input type="text" ref={inputElRef}/>

<input type="text" />

</div>

)

} }

export default InputRef;`

Just a side note here. We will have to access the ref using the current property which gives us access to current reference.

Refs with react hooks

To use Refs in React hooks we have a hook provided by React — useRef.

import React , { useEffect , useRef } from 'react' const inputRef = (props) => { const inputElRef = useRef(null);

useEffect(() => {

inputElRef.current.focus();

}, []) return (

<div>

<input type="text" />

<input type="text" ref={inputElRef}/>

<input type="text" />

</div>

)

}

export default inputRef;

Side Note: We can pass an initial value in useRef to store any value, hence useRef is not just used to get access for the DOM element but we can store any other values as well. For this example, however, we pass null as an initial value.