Suck Less at React: Understanding refs

eddyw
3 min readNov 1, 2017

--

Refs let us access the instance of a child. As stated in the React docs, the child can be an instance of either a React Component or a DOM Element.

Once again, if you didn’t get why I highlighted the word instance, let’s look at a working example:

What we have here is a Component and a React Element which are given refs. You can see that our two Ref Handler methods will return:

span html element: true // ref instanceof HTMLSpanElement
Span Component: true // ref instanceof Span

The first ref to the HTML span element will give us access to all methods and properties of an instance of an HTMLSpanElement such as innerHTML and textContent.

However, the second ref to the React Component will give us a different kind of access. It will allow us to access a Component’s instance properties and methods such as context, props, and even state but that’s not all, we can also have access to the setState method and forceUpdate. Not that we should but that means we could set the state of a child component or force it to update.

Usually, you won’t need access to a Component’s instance properties or methods but they can come in handy for building tools.

On the other side, accessing a HTML DOM Element’s instance properties and methods is more commonly used. Usually to integrate with third party libraries or build uncontrolled Components.

Where is my good example for accessing a Component’s instance properties and a HTML DOM Element’s instance properties? Here:

Let’s suppose we have a Form component with a form element inside that has one or several inputs. We can use the onSubmit event to handle the event when the form is submitted:

Everything so far is pretty simple, when you press enter inside the input element the form will trigger the onSubmit event. However, what happens if you want to trigger this event manually. For example, in the hypothetical case the user is leaving the current page and you ask the user if they want to submit the changes or discard them. How would you trigger the onSubmit event manually?

For the purpose of this example, we are going to add a button that is outside of the Component that we want to use to trigger this event manually. We can refactor our code to let the Form Component expose the HTML DOM Instance of the form element. So, in can be accessed through a Component’s instance properties:

As you can see, with little change in our Form component, we exposed the instance of the form element. Then, accessing the ref of our Form Component gives us access to its instance properties. Thus, access to the form ref which we can later use to dispatch custom events. In this case, we dispatch the submit event.

The good thing about this approach is that the Form Component can be used without the ref just like in the previous example. However, it allows the developer to access its refs for more powerful options.

As a last note, do not abuse of refs and don’t misuse them trying to “fix React”. Most of the times, it’s your fault if something doesn’t work and a bit of refactoring and proper design can give you the results you want.

Read more about refs in the official documentation of ReactJS: https://reactjs.org/docs/refs-and-the-dom.html

As a bonus point…

Yes, you could write you Form Component as a Functional Component like this:

However, be careful. Functional Components do not return a React Component instance. Thus, you can’t do:

Even though, this will likely work fine in React v15, you will see a horrible warning regarding this issue in React v16 and you’re code will probably break in future releases if you ignore the warning.

Don’t make writing Functional Components a synonymous of laziness. You can convert a Functional Component to a Class Component easy by typing a few lines of code when you must.

If you know other uses of refs or have an opinion regarding the topic, you are free to leave a comment below.

--

--