How do refs work in React?
What are refs?
Refs give you a way of accessing DOM nodes or React elements that are created in the render
method of a component.
What to use refs for?
- Store a reference to a DOM node. Useful for managing focus, text selection, or media playback (e.g.,
myInputRef.focus()
). - Integrating with third-party DOM libraries. Many libraries require you to imperatively operate on a DOM node (e.g.,
mySelectEl.initializeFancyPlugin()
).
Use refs in class components
Add a ref to a DOM element
You typically assign refs to an instance property so that they can be referenced throughout the component
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// create a ref to store the textInput DOM element
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// Explicitly focus the text input using the raw DOM API
// Note: we're accessing "current" to get the DOM node
this.textInput.current.focus();
}
render() {
// tell React that we want to associate the <input> ref
// with the `textInput` that we created in the constructor
return (
<div>
<input
type="text"
ref={this.textInput} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
Add a ref to a class component instance
You can also assign refs to a mounted instance of a class component. In the example below, this.textInput
will refer to the mounted instance of CustomTextInput
:
class AutoFocusTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
}
componentDidMount() {
this.textInput.current.focusTextInput();
}
render() {
return (
<CustomTextInput ref={this.textInput} />
);
}
}
This will only work if CustomTextInput
is a React class component.
Access a ref
const node = this.myRef.current;
The value of current
will be:
- The underlying DOM element when the ref is used on a DOM element.
- The mounted instance of the component when the ref is used on a custom class component.
Use refs in function components
function CustomTextInput(props) {
// textInput must be declared here so that the ref is accessible
// in the JSX returned below
const textInput = useRef(null);
function handleClick() {
textInput.current.focus();
}
return (
<div>
<input
type="text"
ref={textInput} />
<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}
Refs and the component lifecycle
Ref assignments are made before the componentDidMount
and componentDidUpdate
lifecycle methods. This means you’ll have access to any refs inside those methods.
When a component unmounts, refs are set to null
.
Callback refs
Instead of directly passing the ref created from React.createRef
to the ref
JSX attribute, you can also pass a callback function. This function receives the underlying DOM node or component instance as an argument.
Ref callbacks may sometimes be preferable when you need to:
- Store a reference directly in an instance property and so avoid using the
createRef
orcurrent()
. Mainly to improve code readability. - Run code when React attaches or detaches a ref to a DOM node. This can be useful when integrating with third-party DOM libraries.
Here’s an example usage of ref callbacks:
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.setTextInputRef = element => {
this.textInput = element;
};
this.focusTextInput = () => {
// Focus the text input using the raw DOM API
if (this.textInput) this.textInput.focus();
};
}
componentDidMount() {
// autofocus the input on mount
this.focusTextInput();
}
render() {
// Use the `ref` callback to store a reference to the text input DOM
// element in an instance field (for example, this.textInput).
return (
<div>
<input
type="text"
ref={this.setTextInputRef}
/>
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
The callback will be called with the underlying input element when the component mounts, and with null
when it unmounts.
Pass refs between components using callback refs
Callback refs also let you pass refs between components like so:
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class Parent extends React.Component {
render() {
return (
<CustomTextInput
inputRef={el => this.inputElement = el}
/>
);
}
}
Other notes
- Whilst not recommended in most cases, you can expose DOM refs to parent components.
Sources
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment