Skip to main content

Command Palette

Search for a command to run...

How to Dynamically Add Refs In React

Updated
•4 min read

Refs are a way to access DOM nodes or React elements just as you would access DOM elements in vanilla JavaScript if you use document.querySelector or document.getElementById. The syntax is very different, but it serves about the same purpose.

You should however use Refs sparingly and only use it if and only if it is necessary, you can read more about that here.

To add refs to React components, we first create a ref, and then we add the ref to the component using the ref attribute. There are two ways to create refs in React the first is by using React.createRef() method or the useRef() hook. In this article, we will be using the hook.

One common use case for refs is to focus on elements based on certain events. Assume we have an input element that automatically gets focus when you click on a button, it will make sense to add an onClick event on the button that sets focus on the input element. Look at the example below

First, we import the useRef hook and use it to create a ref, passing null to it as an argument. This means that at the point of creation, the ref does not reference any DOM element. This value can be accessed from the ref's current property i.e at the point of creation myRef.current = null because we set the initial value to null. In order to make the ref reference a DOM element we assign myRef to the ref prop of the input element so that myRef is now a reference to the input element which can be access from myRef.current.

Next, we set the button onClick event to set focus on the input element.

This does the work if we only have to add ref to a single element and nothing more, but assume we have to create a new SingleRefNode component dynamically, say on clicking a button. This method obviously won't work, because our ref can only reference a single DOM element at a time, and if we want to create many DOM elements that have refs, we need to be able to add the refs dynamically.

To achieve this we need to use another method of adding refs to elements called ref-setter function, the ref-setter function does the same thing but assigns a function to the ref prop instead of the ref object itself(myRef). For example;

We imported a component named MyNode, it is a class component that we will add to the DOM dynamically, but we will talk about that later. Notice how we imported the useRef hook and this time we set the initial value to an empty array - this is so that we can have an array of refs where each ref in the array references a DOM element in another array which I created using the state hook also initialized to an empty array. Here we render two components, a button that triggers the addNode function on click and adds a new MyNode to the state which is then rendered in the div below it. The addNode function is the handler for the onClick event on the button.

Notice how I passed the ref to MyNode, I did not assign it to the ref prop of MyNode - I did this so that we can forward nodesRef to MyNode and then add it to an input component that will be rendered inside MyNode, this way each current property of nodesRef will point to the right input element.

Now let's go back to MyNode:

MyNode is a class component because we need to attach the ref to an instance of the component itself and then add it to any of its children, and function components do not have instances, so we can only use class components for this purpose.

After attaching the ref to MyNode using:

we go on to add the ref to the input component, this time using the ref prop of the component and once again using the ref-setter function. So now the current property of nodesRef will be an array of the references to every input component that is rendered in MyNode.

Thank you for reading through. The complete code is available here, I hope this will be helpful or has been helpful to you. If you have any comments or suggestions, please drop them below.

āœŒšŸ¾