DEV Community

Joseph Mawa
Joseph Mawa

Posted on

What is useRef hook and how do you use it?

Alt Text

This is the sixth article of React Hooks series. If you haven't read the first five articles, you can find them at the links below.


Content Outline


What is useRef hook?

A hook is a special function which enables one use state and other React features without writing ES6 class components which are generally considered difficult to understand, use and master.
useRef hook is part of the React Hooks API. It is a function which takes a maximum of one argument and returns an Object. The returned object has a property called current whose value is the argument passed to useRef. If you invoke it without an argument, the returned object's current property is set to undefined. The code below illustrates how to invoke the useRef hook in functional components.

const myRef = React.useRef(null);
// You can use a descriptive variable name instead of myRef.
Enter fullscreen mode Exit fullscreen mode

myRef, which is returned by a call to useRef hook is an object which looks like {current: null}. If invoked without an argument, then the returned object is {current: undefined}

What purpose does useRef hook serve?

Some of the use cases of useRef hook are:

  1. To access DOM elements
  2. To persist values in successive renders

Accessing DOM elements

One of the most common use case of useRef hook is to access DOM elements (NOT custom React component). For example if you want to access an input element after it has been mounted to the DOM, instead of using document.getElementById, document.querySelector or any other method for selecting DOM elements like in vanilla javascript, you can use useRef hook. This is illustrated in the example below.

import React from "react";
import ReactDOM from "react-dom";

const App = (props) => {
  const inputRef = React.useRef(null);
  React.useEffect(() => {
    console.log(inputRef.current);
    inputRef.current.focus();
  }, []);
  return (
    <form>
      <input 
        type="text"
        placeholder="Enter Name" 
        name="name" 
        ref={inputRef} />
    </form>
  );
};
const root = document.getElementById("root");
ReactDOM.render(<App />, root);

Enter fullscreen mode Exit fullscreen mode

In the code above, App component returns a form element. useRef hook is invoked and null is passed as an argument. useRef returns an object, {current: null} which is assigned to inputRef. inputRef is an object whose current property is initially set to null. Since it is passed as value of input element's ref attribute, the value of current property is then set to input DOM element. input element can then be accessed and manipulated via inputRef's current property.

WARNING

Though useRef makes it easy to manipulate DOM elements, you are discouraged from using it willynilly. There are specific use cases where it is advisable to use useRef hook. Read more about them at
React Documentation.

To persist values in successive renders

There are situations where you might want to persist certain values in consecutive renders. Instead of storing these values in state which might cause unnecessary renders, you can store it as the value of useRef's current property since react guarantees that this value is persisted between re-renders. Furthermore, if you want to determine state value from previous state values, it is advisable to use useRef hook to persist them. This is very helpful because in functional components, state is not merged but completely replaced.

Using ref with class components

It should be noted that useRef hook is available only for functional components. If you want to reference a DOM element in class components, you can use React.createRef API. Like the useRef hook in functional components, React.createRef takes a maximum of one argument and returns an object with current property set to the argument passed and undefined if no argument is passed. The object returned by creatRef is stored in an instance property during construction like this.myRef = React.createRef().

class App extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef(null);
  }
  componentDidMount() {
    console.log(this.inputRef.current);
    this.inputRef.current.focus();
  }
  render() {
    return (
      <form>
        <input
          type="text"
          placeholder="Enter Name..."
          name="name"
          ref={this.inputRef} // or ref = {e => this.inputRef.current = e}
        />
      </form>
    );
  }
}

const root = document.getElementById("root");
ReactDOM.render(<App />, root);

Enter fullscreen mode Exit fullscreen mode

The object returned by calling React.createRef is assigned as value of ref attribute of the DOM element we want to reference. You can also achieve the same thing by using:
ref = {element => this.inputRef.current = element} instead of ref={this.inputRef}.

NOTE

It is worth pointing out that createRef and useRef hook can be used for creating ref in functional components. However, refs created using createRef are not persisted between re-renders. A new ref is always created whenever the component is re-rendered.

You should also note that React will not be notified of any changes to a component's ref.

Summary

In summary, this article looked at:

  • An overview of hooks and the React Hooks API
  • Purpose of useRef hook
  • The useRef hook and how to use it in functional components
  • Use of createRef API in ES6 class components

Thanks for reading this article up to the end. If you notice anything technically inaccurate, you can comment below. If you find this article useful, you can share it on Twitter so that others also benefit from it.

REFRENCES

Top comments (6)

Collapse
 
erchis profile image
erchis

What's the difference between useRef() and useRef(null)? I prefer, and could go with the undefined all the time, but online examples always go with the null. So I am wondering.

Collapse
 
nibble profile image
Joseph Mawa

It is up to you to decide which one of the two to go with. The reason why people go with null over undefined boils down to the difference between the two. You can read about it here.

Collapse
 
mcntai profile image
mcntai

What a detailed and quality guide. Well done!

Collapse
 
nibble profile image
Joseph Mawa

Hello there. Thanks for the feedback.

Collapse
 
hazberi profile image
Hassaan Zuberi

This is possibly the best post ever on useRef. I was having a hard time to understand this concept but your explanation was on point. Thanks a lot. Really appreciate.

Collapse
 
nibble profile image
Joseph Mawa

Thanks. I am glad you found it useful.