A gentle introduction to Refs in React

When to use Refs

When it’s okay to use refs? Well, the react docs provide some guidance. According to the docs, you should consider using refs when you need to:

  • Manage focus, text selection, or media playback.
  • Perform imperative animations.
  • Integrate with third-party DOM libraries.

When to NOT use Refs

In general, you avoid using refs for things that can be done declaratively. An example is updating the background colour of a div, in response to a click event.

Creating Refs — Using React.createRef()

You can create refs using React.createRef() and attach them to React elements via the ref attribute. Essentially, you assign the Ref returned from React.createRef() to an instance property, when a component is constructed (aka, in the component’s constructor). This way, the Ref can be referenced throughout the component.

Creating Callback Refs

Another way to set refs in React is to use callback refs. With this method, instead of passing a ref attribute created by createRef(), you pass a function that, when called, receives the React component instance or HTML DOM node as its argument, which can be stored and accessed elsewhere. Here’s what that looks like:

Example using callback refs
Ref callback as an inline function

When does the callback get called?

We’ve talked of how the callback will get called with the appropriate element, but when exactly does this happen? Put differently, the question is, when can I expect that the ref, which in our example above, is inputRef will be set. Thankfully, the React docs are very clear on this:

Accessing Refs

How do you access a ref’s underlying DOM node or React element? Well, that depends on how you created the ref.

Accessing Refs created with createRef()

React.createRef() returns an object with a current property.

The object returned by React.createRef()
Accessing refs created with React.createRef()

Accessing Callback Refs

Unlike the createRef() approach, when you a callback ref, the callback function you provide is called with the actual React component instance or HTML DOM node, as its argument.

Accessing callback refs

A quick note about functional components

Remember how we said, that, when attached to your custom components, a ref’s current property receives the mounted instance of that component? Well, for functional components, this means that attaching a ref via the ref attribute won’t work, because functional components are, well, just functions and so there won’t be an instance to work with. The example below attempts to attach a ref to a functional component.

Attaching a `ref` to a functional component won’t work as expected

What if I want to access a child component’s DOM Refs from a parent component?

In rare cases, you might want to access a child’s DOM node from a parent component. While not recommended, because it breaks component encapsulation, but it can occasionally be useful for triggering focus or measuring the size or position of a child DOM node.

With React 16.3 or higher

If you use React 16.3 or higher, it is recommended that you use ref forwarding — a technique for automatically passing a ref through a component to one of its children. This feature essentially allows a component to take a ref they receive, and pass it further down to a child.

Example using Ref forwarding

Using ref forwarding with Higher Order Components (HOCs)

The key thing to note here is, if you pass a ref to a HOC it will not get passed through to the wrapped component. Instead of referring to the wrapped component, the ref will refer to the outermost container component. This is because when React encounters a ref attribute on a component, it attaches the ref to the HTML element or component on which the attribute was set. This is not what we want. Although we are setting the ref on the HOC, we really want the ref to get forwarded down to the wrapped component, instead of being attached to the HOC.

Using ref forwarding with HOCs

With React versions below 16.3

React 16.2 and earlier doesn’t yet support ref forwarding. If you need to expose a DOM ref to components above and can’t migrate to React 16.3+ yet, you can use the following approach instead.

Conclusion

Refs offer a great way to pass data down to a child instance, outside outside of the typical data flow. While really come in handy for situations where you really need to access and manipulate DOM elements, you should be careful not to overuse refs.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store