In React, managing focus programmatically is a common requirement, especially when building interactive or accessible UIs. The useRef
hook in React provides an efficient way to directly access and manipulate DOM elements, including managing focus.
1. What is useRef
?
useRef
is a React hook that allows you to persist values across renders without triggering a re-render. It can be used to directly reference DOM elements or store mutable values. When used to reference a DOM element, useRef
provides a way to interact with that element directly (e.g., for focus management, measurements, or other DOM manipulations).
Syntax of useRef
:
const myRef = useRef(initialValue);
initialValue
: This is the initial value of the reference. For DOM elements, this is usuallynull
until the component mounts.
2. How to Manage Focus with useRef
To manage focus in React, you can assign a ref
to an input (or any focusable element), and then use useRef
to reference that element. Once the element is referenced, you can programmatically call methods like focus()
on it.
3. Example: Focusing an Input Field on Button Click
Let’s create a simple example where clicking a button will focus an input field using useRef
.
import React, { useRef } from 'react';
const FocusExample = () => {
const inputRef = useRef(null);
const handleFocus = () => {
// Focus the input field
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Click the button to focus" />
<button onClick={handleFocus}>Focus Input</button>
</div>
);
};
export default FocusExample;
Explanation:
inputRef
: We create a reference to the input field usinguseRef(null)
.ref={inputRef}
: We assign theinputRef
to the input element to reference it.handleFocus
: This function usesinputRef.current.focus()
to focus the input field when the button is clicked.
In this example, every time the user clicks the “Focus Input” button, the input field will gain focus.
4. Example: Auto-Focusing on Mount
You can also use useRef
to focus an input field automatically when the component mounts by using the useEffect
hook.
import React, { useEffect, useRef } from 'react';
const AutoFocusInput = () => {
const inputRef = useRef(null);
useEffect(() => {
// Automatically focus the input field when the component mounts
inputRef.current.focus();
}, []);
return <input ref={inputRef} type="text" placeholder="I am focused on mount!" />;
};
export default AutoFocusInput;
Explanation:
useEffect
: This hook runs once after the component mounts (because of the empty dependency array[]
). Inside theuseEffect
, we callinputRef.current.focus()
to set focus to the input field immediately after the component is rendered.
5. Example: Managing Focus in a Form
In a form with multiple inputs, you may want to set focus on a specific input field based on certain conditions (e.g., focus the next input after a user enters data).
import React, { useState, useRef } from 'react';
const FormExample = () => {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const nameRef = useRef(null);
const emailRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
if (name.trim() === '') {
nameRef.current.focus(); // Focus the name input if empty
} else if (email.trim() === '') {
emailRef.current.focus(); // Focus the email input if empty
} else {
alert('Form Submitted!');
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>Name</label>
<input
ref={nameRef}
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div>
<label>Email</label>
<input
ref={emailRef}
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<button type="submit">Submit</button>
</form>
);
};
export default FormExample;
Explanation:
- Focus Management: If the user submits the form with the
name
oremail
input empty, we useuseRef
to focus the relevant input field. nameRef
andemailRef
: These references are assigned to the respective inputs, allowing us to control which input should be focused upon form submission.
6. Example: Focus Management in a Modal
If you have a modal dialog and want to manage focus, you can use useRef
to ensure focus is automatically set on a specific element when the modal is opened.
import React, { useState, useRef, useEffect } from 'react';
const Modal = ({ isOpen, onClose }) => {
const closeButtonRef = useRef(null);
useEffect(() => {
if (isOpen) {
// Focus the close button when the modal opens
closeButtonRef.current.focus();
}
}, [isOpen]);
return (
isOpen && (
<div className="modal">
<div className="modal-content">
<button ref={closeButtonRef} onClick={onClose}>
Close Modal
</button>
</div>
</div>
)
);
};
const App = () => {
const [isModalOpen, setModalOpen] = useState(false);
const openModal = () => setModalOpen(true);
const closeModal = () => setModalOpen(false);
return (
<div>
<button onClick={openModal}>Open Modal</button>
<Modal isOpen={isModalOpen} onClose={closeModal} />
</div>
);
};
export default App;
Explanation:
- Modal Focus: When the modal is opened, we set focus to the close button using
useRef
. closeButtonRef
: This reference is attached to the close button, ensuring that the button gets focused when the modal opens.
7. Benefits of Managing Focus with useRef
- Enhanced Accessibility: Managing focus programmatically can improve the accessibility of your application, especially for keyboard and screen reader users.
- Improved User Experience: By controlling focus (e.g., auto-focusing fields or buttons), you can provide a smoother and more intuitive experience for users.
- More Control: Direct access to DOM elements allows for finer control over interactions, making it easy to manage complex UIs and forms.