Categories
React

How to Assign Multiple Refs for an Array of Elements with React Hooks?

Spread the love

In React components, we can assign refs to elements in a component so that we can get access to them in the component code.

Sometimes, we have multiple elements that we want to get access to in our code via refs.

In this article, we’ll look at how we can assign multiple refs to an array of elements with React hooks.

Assign Multiple Refs for an Array of Elements

One way to assign refs for multiple elements rendered from an array is to store the refs in a state.

For instance, we can write the following:

import { createRef, useEffect, useState } from "react";

const arrLength = 5;
export default function App() {
  const [elRefs, setElRefs] = useState([]);
  console.log(elRefs);

  useEffect(() => {
    setElRefs((elRefs) =>
      Array(arrLength)
        .fill()
        .map((_, i) => elRefs[i] || createRef())
    );
  }, []);

  return (
    <div>
      {Array(arrLength)
        .fill()
        .map((el, i) => (
          <div ref={elRefs[i]} key={i}>
            {i}
          </div>
        ))}
    </div>
  );
}

We defined the elRefs state which has an empty array as its initial value.

Then we add the useEffect callback that calls setElRefs to populate the elRefs state with an array of refs.

To do this, we create an empty array with length arrLength .

Then we call fill to fill the empty slots so we can call map on it to add the refs.

Then we call map with a callback to either return the existing ref or call createRef to create a new ref and return it.

The empty array in the 2nd argument of useEffect indicates that we only run the callback once when we mount the component.

Below that, we render an array with length arrLength to divs by calling map with a callback to return a div with the ref assigned to it.

We assign a ref to each div rendered with the ref prop.

We just pass in the elRefs[i] value to it to assign the ref.

The key prop has to be set to a unique value so that React can identify the rendered elements properly.

Now when we log the value of elRefs as we did in App , we should see 5 objects in an array with the current value of each set to the element that we rendered.

Alternatively, we can create a ref with the useRef hook and set the current value to an array.

Then we can populate the array with the elements.

To do this, we write:

import React, { useRef } from "react";

const arrLength = 5;
export default function App() {
  const refs = useRef();
  refs.current = [];
  console.log(refs);

  const addToRefs = (el) => {
    if (el && !refs.current.includes(el)) {
      refs.current.push(el);
    }
  };

  return (
    <div>
      {Array(arrLength)
        .fill()
        .map((el, i) => (
          <div ref={addToRefs} key={i}>
            {i}
          </div>
        ))}
    </div>
  );
}

We set the refs.current value to an empty array.

Then we define the addToRefs function to call refs.current.push with el to add el to the refs.curent array.

el is the element which is assigned the addToRefs function to the ref prop.

So el would have the rendered divs since they have the ref prop set to addToRefs .

Therefore, refs.current is an array with all the rendered elements.

Conclusion

We can create refs and assign them to multiple elements or create a single ref with an array and add all the elements object to it in a React component.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *