React: How to handle external and Internal refs in the same element.

Danilo Peña
2 min readJul 9, 2021
Multiple Refs

Suppose that you are building a design system or that the project you are building requires many reusable components. For most of those components, you need to expose a ref of the element for you to use near in the future or any other consumer or co-worker.

You can do that with React’s forwardRef. Look at this simple Dropdown Menu component (this could be an item inside of a Menubar component, for example)

Here at this simple Dropdown, we have a hard-coded list with two options, the button’s label passed by props and a simple handler for the click event that switches the aria-hidden property for displaying the menu. With forwardRef we can pass an external reference to the button from any parent component.

Alright. This is how it looks:

But… What if I want the button label to be a longer string? The min-width for both button and list is the same value, but I want that min-width for the menu to be the same width as the button’s width.

One of that workaround would be to create an internal reference of the button and another one for the menu to get the button’s width and assign it to the menu as min-width property.

But… wait! We do have already a ref from an external parent assigned to the button… what can we do?

So simple, React provides to us a Hook that makes our lifes easier: useImperativeHandle. As the docs said, useImperativeHandle customizes the instance value that is exposed to parent components when using ref.

Thats it! Now we can access and manipulate internal refs and pass an external ref to the Dropdown component.

const ref = React.createRef();return <Dropdown ref={ref} />;

Last but not least, you can check the complete example on this sandbox.

--

--