Design Converter
Education
Last updated on Feb 26, 2025
•5 mins read
Last updated on Feb 26, 2025
•5 mins read
Struggling to manage focus across multiple input fields in React?
Need a way to track several elements without unnecessary re-renders?
Using a React array of refs can help. This approach lets you store references to multiple elements, making tasks like focus management, form validation, and custom interactions much easier.
This blog walks through using the useRef hook with multiple inputs, managing DOM nodes, and keeping performance smooth. By the end, you’ll know how to handle an array of refs effectively in your React components.
A ref (short for reference) provides a way to directly interact with a DOM node or an instance of a React component without triggering a re-render. The useRef hook creates a ref object with a current property that persists across re-renders.
A ref object can be created using the useRef hook and assigned to an element using the ref attribute.
1import { useRef, useEffect } from "react"; 2 3function SingleInputFocus() { 4 const inputRef = useRef(null); 5 6 useEffect(() => { 7 inputRef.current.focus(); // Automatically focuses on the input field 8 }, []); 9 10 return <input ref={inputRef} type="text" />; 11}
In this example, the input ref ensures the input field is focused when the component renders.
Handling multiple input elements dynamically requires an array of refs. Instead of creating multiple individual ref objects, an array can store multiple references efficiently.
Common use cases include:
• Navigating between multiple input fields with keyboard shortcuts
• Managing focus dynamically based on user interactions
• Handling form validations without relying on state changes
An array of refs can be initialized using an empty array inside a useRef hook. The map function helps generate multiple input ref assignments dynamically.
1import { useRef } from "react"; 2 3function MultiInputFocus() { 4 const inputRefs = useRef([]); // Initializing an empty array of refs 5 6 const focusNext = (index) => { 7 if (inputRefs.current[index + 1]) { 8 inputRefs.current[index + 1].focus(); 9 } 10 }; 11 12 return ( 13 <div> 14 {Array.from({ length: 5 }, (_, index) => ( 15 <input 16 key={index} 17 ref={(el) => (inputRefs.current[index] = el)} 18 type="text" 19 onKeyDown={(e) => e.key === "Enter" && focusNext(index)} 20 /> 21 ))} 22 </div> 23 ); 24}
• The array of refs is stored inside useRef([])
, ensuring persistence across re-renders.
• The ref attribute assigns each DOM node to its corresponding ref object inside the array.
• The focusNext function shifts the focus to the next input field when the user presses "Enter".
One of the benefits of using an array of refs is that it does not cause re-renders when updated. Unlike state changes, modifying a ref object does not trigger a component re-render.
1import { useRef, useState } from "react"; 2 3function ControlledReRendering() { 4 const inputRefs = useRef([]); 5 const [values, setValues] = useState(Array(5).fill("")); 6 7 const handleChange = (index, event) => { 8 const newValues = [...values]; 9 newValues[index] = event.target.value; 10 setValues(newValues); // Updates state, triggering a re-render 11 }; 12 13 return ( 14 <div> 15 {values.map((value, index) => ( 16 <input 17 key={index} 18 ref={(el) => (inputRefs.current[index] = el)} 19 type="text" 20 value={value} 21 onChange={(e) => handleChange(index, e)} 22 /> 23 ))} 24 </div> 25 ); 26}
• Updating the ref object does not cause a re-render, but updating the values state does.
• The only exception to causing a re-render is if a ref is used inside a state update.
• This approach ensures that the component updates only when needed, optimizing performance.
A custom component can accept an array of refs and allow a parent component to control multiple input fields.
1import { forwardRef } from "react"; 2 3const CustomInput = forwardRef(({ index }, ref) => { 4 return <input ref={ref} type="text" placeholder={`Input ${index + 1}`} />; 5});
1import { useRef } from "react"; 2import CustomInput from "./CustomInput"; 3 4function ParentComponent() { 5 const inputRefs = useRef([]); 6 7 return ( 8 <div> 9 {Array.from({ length: 3 }, (_, index) => ( 10 <CustomInput key={index} ref={(el) => (inputRefs.current[index] = el)} index={index} /> 11 ))} 12 <button onClick={() => inputRefs.current[0]?.focus()}>Focus First</button> 13 </div> 14 ); 15}
• forwardRef allows passing a ref to a custom component.
• The parent component controls the input refs and sets the focus dynamically.
To iterate over DOM nodes in an array of refs, the map function can be used.
1const logAllValues = () => { 2 inputRefs.current.map((ref, index) => { 3 console.log(`Input ${index} value:`, ref?.value); 4 }); 5};
This function logs the current value of all input fields without causing re-renders.
A common mistake is not initializing the array inside the useRef hook, leading to null references.
❌ Incorrect:
1const inputRefs = useRef(); // This will not work
✅ Correct:
1const inputRefs = useRef([]); // Initialize as an empty array
If an array of refs is used improperly, the ref prop may not function as expected. Always ensure that each input ref is properly assigned inside the ref attribute.
Managing multiple refs in React can simplify working with input fields and interactive elements. The React array of refs helps keep components organized and improves performance by reducing unnecessary re-renders. Whether handling form inputs or custom event listeners, this approach makes complex tasks easier. Try it in your next project to see the difference.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.