Need to access native DOM nodes in React? Ref is here to help you 👌🏽
In this tutorial we will cover some of the common Ref use-cases:
Using useRef hook, we can use the Ref API in function components.
All the code snippets will be using React Hooks & function components. But, you can easily write the same logic in Class components.
Are you ready? Let's start with managing focus! 😎
Use-case: We would like to use React to put the focus on an HTML element.
Here is a simple version of how we can focus an input field.. 👇🏽
import React, { useRef } from 'react';
const RefFocus = () => {
const inputRef = useRef(null);
function focusTitle() {
inputRef.current.focus();
}
return (
<div>
<label>You have 3 wishes...</label>
<input ref={inputRef} />
<button onClick={focusTitle}>Focus & Wish</button>
</div>
);
};
export default RefFocus;
By calling the function focusTitle we can call the native DOM's focus() function. 🔥
Next in line is highlighting text... 🖋
Use-case: We would like to use React to select a textarea's value.
Here is a minimal example of how you could do that:
import React, { useRef } from 'react';
const RefSelectAll = () => {
const inputRef = useRef(null);
function selectAll() {
const hasText = inputRef.current.value.length > 0;
if (hasText) {
inputRef.current.select();
}
}
return (
<div>
<label>What is the meaning of life?</label>
<textarea ref={inputRef} />
<button onClick={selectAll}>Select All</button>
</div>
);
};
export default RefSelectAll;
We can extend this technique further! Let's do a bit more fancy things like auto-copy some text.
function copyMeaningOfLife() {
const hasText = inputRef.current.value.length > 0;
if (hasText) {
inputRef.current.select();
document.execCommand('copy');
// ... Let user that their meaning of life answer is copied
}
}
So now you can do something like this...✨
Do you feel like you already have super-powers? 😁
Let's see what else you can do...what about media players? 🎵
Use-case: We would like to use React to control HTML's native video element.
Here is how a minimal media player may look like:
import React, { useRef } from 'react';
const VideoPlayer = () => {
const videoRef = useRef(null);
function playVideo() {
videoRef.current.play();
}
function pauseVideo() {
videoRef.current.pause();
}
return (
<div>
<video ref={this.myVideo} width="400">
{/* Of course it's the big buck bunny! */}
<source src="big-buck-bunny.mp4" type="video/mp4" />
</video>
<div>
<button onClick={playVideo}>Play</button>
<button onClick={pauseVideo}>Pause</button>
</div>
</div>
);
};
export default VideoPlayer;
Now you can play & pause your video using React.
If you read the React Docs, you will notice they mention one more use-case. It is about triggering animations.
Let's have a look...
Use-case: We would like to use React to listen to DOM's events & trigger some animations.
Here is a simple version of you can achieve this:
P.S: The code snippet itself doesn't have any animations! 😅
With that said, you can pretty much add all the animations you want following the same technique.
import React, { useEffect, useState, useRef } from 'react';
function ImperativeAnimations() {
const [background, setBackground] = useState('white');
const divRef = useRef();
function onScroll(params) {
const div = divRef.current;
const { y } = div.getBoundingClientRect();
const backgroundColor = y <= 0 ? 'white' : 'pink';
setBackground(backgroundColor);
}
useEffect(() => {
window.addEventListener('scroll', onScroll);
return () => {
window.removeEventListener('scroll');
};
}, []);
return (
<div ref={divRef} style={{ height: '120vh', background: background }}>
Scroll to turn background white.
</div>
);
}
export default ImperativeAnimations;
Here is how our sophisticated animations look like: 😁
Now you know your way around the basic use-cases of Refs, rock on... 🙏🏽
Enjoyed the article? Share the summary thread on twitter.