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:
Originally posted on Nordschool.
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! 😎
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... 🖋
Text Selection
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? 🎵
Media playback
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...
Triggering Imperative Animations
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... 🙏🏽
Support
Enjoyed the article? Share the summary thread on twitter.
Better Code Monday Newsletter
You might also like my newsletter. The idea is to share 3 web dev tips every Monday.
My goal is to improve my writing skills and share knowledge as much as possible. So far, few hundreds of developers have subscribed and seem to like it.
To get a feeling of what kind of stuff I share, Check out the previous newsletter issues and subscribe.
Top comments (0)