Storing an array of elements using the useRef hook

Date Published:

React refs are useful for when we have to set focus to an element after the user has interacted with it. In my case, I needed to use refs for setting focus to the correct accordion item when I selected/used arrow keys.

The problems I faced while doing this was a mixture of having issues with passing down refs into my components but also having one ref that represented an array of items just as you would in a none react app using document.querySelectorAll().

The problem

When there is only one ref we tend to simply assign our ref value with the variable that creates the useRef function.

const item = useRef(null)
<div ref={item}/>

In my use case I could not simply assign my ref to the element because the ref was being assigned within a map during the render. This would mean that the very last item in the array would be the element assigned to item.current.

The solution

The ref prop gives us the element as a parameter which allows us to assign the element however we want. In the example, we push that element into the itemsEls.current array so it can be used further down the line.

const itemEls = useRef(new Array())
items.map(item => (
 <p key={item} ref={(element) => itemEls.current.push(element)}>{item}</p>
))

Note: The same approach applies for an object with ids as a key.

const itemEls = useRef({})
items.map((item, index)) => (
 <p key={item} ref={(element) => itemEls.current[index] = element}>{item}</p>
))

And thats it! We can now store an array of refs in one variable to use when the use case crops up.

Note: this example of assigning a ref to a p tag is purely for simplicity of the code. A good use case for this is when building things that need focus applying to them when the user interacts with the component like an Accordion/Tabs/Modal.

import React, { useRef, useEffect } from 'react'
export const Component = ({ items }) => {
  const itemsEls = useRef(new Array())
  
  return (
    {items.map((item) => {
      const getRef = (element) => (itemsEls.current.push(element))
      return <p key={getRef}>{item}</p>
    })}
  )
}

Thank you for reading.

Back to blogs