Storing Multiple Elements in a Single Ref in React

In some cases, you may want multiple references in a component of unknown quantity. Here’s how you can make it work.

A typical use of the useRef hook is to be able to access the HTML element directly. This is the example from the React docs:

function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
return (
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>

This unlocks the ability to access native properties and call native functions on that element.

Accounting for Multiple (Unknown) Refs

I often run into a scenario in which I want direct access to elements with a component (like the example above), but I don’t know how many components there will be.

Consider if we had a similar component, but rather than focusing a single text input, the button would tab through a series inputs of unknown quantity. In that case, we might track the active input with a state, and then increment the index with each button click.

Because I don’t know how many inputs there will be, I can’t use useRef directly on each one. The workaround is to store the ref as an array ...

const inputEls = useRef([]);

... and then pass a function when applying the reference.

// An example where `idx` is a known index value
<input ref={(el) => (inputEls.current[idx] = el)} type="text" />

In context, that might look something like this:

import React, { useRef, useState } from "react";

export function Component(props) {
const [nextIdx, setNextIdx] = useState(0);
const inputEls = useRef([]);

const onButtonClick = (idx) => {
// Find the new next index.
setNextIdx(nextIdx + 1 >= props.inputCount ? 0 : nextIdx + 1);

return (
.map((_, idx) => (
ref={(el) => (inputEls.current[idx] = el)}
style={{ display: "block", marginBottom: "0.5rem" }}

<button onClick={onButtonClick}>Tab through inputs</button>

That leads to this behavior:


Here’s a playground with this code so you can see it in action.

Let's Connect

Keep Reading

Simple Content Tab with React and Tailwind

The foundation for a tab system begins with a state hook, triggered by clicks on tab elements. View the code snippet and use the playground to see it in action.

May 28, 2022

Run React Effect Hook only Once in Strict Mode

Running React in strict mode with Next.js can lead to useEffect callbacks with zero dependencies to run twice in development. Here’s a way around that.

Jun 25, 2022

Animated Sliding Tabs with React and Tailwind

Add some flair to a simple tab solution by adding an animated bottom border.

May 29, 2022