Understanding and Using Refs in React: Accessing DOM Elements and Component Instances
Learn how to effectively use refs in React for accessing DOM elements and component instances. This tutorial explains when refs are appropriate (direct DOM manipulation, animation, etc.), how to create and use refs, and emphasizes best practices for avoiding over-reliance on refs in favor of declarative approaches.
Working with Refs in React
Refs provide a way to access DOM elements or React components directly. While generally discouraged for managing UI state (which should be done declaratively), refs are useful in specific scenarios.
When to Use Refs
- DOM Measurements: Accessing dimensions, focus, selection, or media playback.
- Imperative Animations: Directly manipulating DOM elements for animations.
- Third-Party Libraries: Integrating with libraries requiring direct DOM access.
- Callbacks: Managing ref updates and cleanup using callback functions.
When NOT to Use Refs
Avoid refs whenever possible for tasks achievable declaratively. For example, control a dialog's visibility using props (e.g., isOpen
) instead of directly calling open()
/close()
methods using a ref.
Creating and Accessing Refs
Refs are created using React.createRef()
(for class components) or useRef()
(for functional components). They're assigned to elements via the ref
attribute. The current property of the ref object gives access to the DOM element or component instance.
Creating and Accessing a Ref (Class Component)
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
handleClick = () => {
if (this.myRef.current) {
this.myRef.current.focus();
}
};
render() {
return (
<div>
<input type="text" ref={this.myRef} />
<button onClick={this.handleClick}>Focus Input</button>
</div>
);
}
}
export default MyComponent;
Ref Types and Properties
The current
property of a ref holds different values:
- HTML Element: The underlying DOM element.
- Class Component: The mounted instance of the component.
- Functional Component: The value passed to useRef().
Refs cannot be directly used on functional components unless you are using the `useRef` hook.
Callback Refs
Callback refs offer more control over when refs are set and unset. Instead of createRef()
, you pass a callback function to the ref
attribute.
Callback Ref Example
import React, { useRef, useEffect } from 'react';
const MyComponent = () => {
const inputRef = useRef(null);
useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
}
}, []); // Focus on mount
return (
<div>
<input type="text" ref={inputRef} />
</div>
);
};
export default MyComponent;
Forwarding Refs
Ref forwarding passes a ref through a component to a child component using React.forwardRef()
. This is commonly used in reusable component libraries.