React/ReactJS: Refs
In React's one-way (or "unidirectional') flow of data, the parent components interact with children via props.
However, in some cases you might need to directly access the
attributes of some elements of a child component and/or modify them,
without re-rendering them with updated props. This is where
refs
come in handy.
Refs
are kind of attributes that offer access to React elements created by
the render()
method. Refs modify the
actual DOM contrast to the virtual DOM philosphy of ReactJS.
The official ReactJS documentation here cites the following three reasons to use refs:
- Managing focus, text selection, or media playback.
- Triggering imperative animations.
- Integrating with third-party DOM libraries.

We create refs using the
React.createRef()
API (introduced in React
16.3, March 2018), which are then added to the JSX elements with the
ref
attribute. The below code illustrates
how it is used.
class SomeComponent extends React.Component {
constructor(props) {
super(props);
this.someRef = React.createRef();
}
render() {
return <div ref={this.someRef} />
}
}
The passed ref
offers access to the
referenced node with the
current
attribute.
const node = this.someRef.current;
In the below section, we make use of ref's
current
attribute to auto-focus on an
<input/>
element.
Using Ref to Focus in an Input Element
The ref
attribute is passed to the
<input/>
DOM element. Using this
ref's current
attribute, the
<input/>
element's
focus()
method is invoked inside
componentDidMount()
to automatically
focus on it right after the component loads.
class TextFocus extends React.Component{
constructor(props) {
super(props);
this.nameInput = React.createRef();
}
componentDidMount() {
this.nameInput.current.focus();
}
render() {
return(
<div>
<input
ref={this.nameInput}
placeholder="Name"
/>
</div>
);
}
}
Callback Refs
There is another way to set refs, without the need of passing any
ref
attribute created by the
createRef()
API in the constructor.
Instead, a function receiving an HTML DOM element or an instance of
a component as an argument is passed. It typically looks as follows:
<input type="text" ref={el => this.textInput = el}/>
In the following section, we will make use of callback ref to
reference a <video>
element and
invoke its play()
and
pause()
methods.
Using Callback Ref to Play/Pause an HTML5 Video
For the purpose of this example, let us import some video of a bird
(bird.mp4
) inside the
/videos
directory. I downloaded this
silent video for free from
https://videos.pexels.com/videos/video-of-a-bird-855097
import bird from './videos/bird.mp4';
This import name will be substituted as a value for the
src
attribute of the
<source>
element.
A callback function is passed to the ref inside the
<video>
element. This callback
stores a reference to this VIDEO
node in
an instance property.
class Video extends React.Component {
constructor(props) {
super(props);
this.state = {
play: false,
}
this.videoClick = this.videoClick.bind(this);
}
videoClick() {
this.state.play? this.video.pause():this.video.play();
this.setState({ play: !this.state.play });
}
render() {
return (
<div>
<video ref={vd => this.video = vd}>
<source
src={bird}
type="video/mp4"
/>
</video>
<div>
<button onClick={this.videoClick}>Play / Pause</button>
</div>
</div>
)
}
}
export default Video;
Note that we do not put the
controls
attribute into the
<source>
element, which would have
enabled video controls like play/pause, full-screen toggle, volume
adjustments and slider. Instead, we added an additional
Play /Pause
button below which on
clicked makes use of the
this.video
callback inside its handler
to toggle the call between the video element's
play()
and
pause()
methods.
Upon rendering, the loaded
<Video/>
component appears as
follows.

Adding Ref to a Class Component
Let us create a class component called
<Name/>
which has a function
called setName()
that sets the value of
the <input/>
element to some
string ("Felix" here). Notice that nowhere we have called this
function inside the component.
class Name extends React.Component{
constructor(props) {
super(props);
this.nameInput = React.createRef();
this.setName = this.setName.bind(this);
}
setName() {
this.nameInput.current.value = 'Felix';
}
render() {
return(
<div>
<input
ref={this.nameInput}
placeholder="Name"
/>
</div>
);
}
}
Instead, we call the function from a parent component called
<AssignName/>
by attaching a ref.
class AssignName extends React.Component{
constructor(props) {
super(props);
this.textInput = React.createRef();
}
componentDidMount() {
this.textInput.current.setName();
}
render() {
return (
<Name ref={this.textInput} />
);
}
}
By the way, if both the above components are in the same file, do
not forget to export the parent component
<AssignName/>
.
export default AssignName;

If the <Name/>
component above
would have been functional (stateless) instead of a class,
ref
would not have worked as they do not
have instances.
Ref with jQuery, a Third-Party DOM Library
Refs are also used when integrating third-party DOM manipulating
libraries like
jQuery with React.
They are attached to the plugin's wrapper element, which usually is
the only child element of the wrapper
<div/>
, so as to avoid conflicts
with React updates. We have a separate tutorial on using jQuery
plugins with React
here.
Notes
- Refs should not be overused; avoid them wherever the desired functionality can be achieved declaratively.
-
The
ref
attribute should not be used on functional components as they do not have instances.