The scary hook ๐ป
This article is based on my phobia of the useRef
hook, and as a self acclaimed nice guy i want to help others feel less traumatized oh yeah that's about.
Blast off! ๐
And without further ado, let's jump on this. useRef
is a hook in React JS, basically introduced in the React 16.3 version. Truth be told, in my view, React hasn't always been this fun. It started out with class components, which was kind of a downer, but proceeded to something I love now: functional React components (legacy.reactjs.org/docs/react-component.html) . Using Hooks provided a way to use state and life-cycle , which were traditionally exclusive to class based React (๐คฎ)
useRef
is multipurpose, but particularly used for working with mutable data that won't cause re-rendering. Being versatile and multipurpose, it proves to be an arsenal important in the war waging against unoptimized codes.
useRef
comes to fight the most commonly used hook ever: the useRef
comes to fight the most commonly used hook ever: the useState
hook. You see, when React developers want to make a change to React or to handle data, they fall to useState
. No biggie; it's cool. In short, it was built for that. But you see, useState
changes re-renders the whole component, which most times we love, but in more than most, we shouldn't.
Persisting Values across Renders ๐
so why shouldn't you like re-renders hun? well lets a little de-tour ; truly re-renders re essential for the dynamic nature of web and mobile applications, allowing user interaction and necessary UI changes but yeah i've seen the dark side ๐
Performance Issues : too many re-renders gives the user a laggy feeling, if your'e an engineer or wannabe you definitely care about users feeling.
Battery Drain : come on man, don't kill the user batteries ๐ข !!,
you see since useRef doesnt cause re-renders (๐) , it's useful for maintaing values that should not trigger re-renders.
function Counter() { const count = useRef(0); // Initialize with a mutable value
useEffect(() => { // Update the value without causing a re-render count.current = count.current + 1;
console.log(Count: ${count.current});
}, []);
return
Check the console for count updates; }
this one trait cuts across to storing previous values of props or state which proves useful in scenarios like comparing current value to previous ones and Closure issues.
Closure Issues
React Components frequently involve asynchronous operations and event handlers making Closures become hell , a basic scenario is if a state changes before a closure is called
useEffect(() => {
const intervalId = setInterval(() => {
// This closure captures the stale value of 'count' console.log(count); }, 1000);
return () => clearInterval(intervalId); },
[]);
look at it, the callback captures the stale value of "count", this is where our buddy comes in
useEffect(() => {
const intervalId = setInterval(() => {
// Access the latest value using countRef.current console.log(countRef.current); }, 1000);
return () => clearInterval(intervalId); }, []);
useEffect(() => {
// Update the countRef.current whenever count changes
countRef.current = count; }, [count]);
Accessing and Modifying DOM Elements
the first use case i ever knew useRef for was accessing and playing with DOM elements, as a mobile dev (React native) , useRef is vital to animations, grab the component and then throw it about or in focusing on a form.
function FocusInput() {
const inputRef = useRef(null); useEffect(() => {
// Focus on the input element when the component mounts inputRef.current.focus(); }, []);
return <input ref={inputRef} />; }
i really do hope iv'e been able to bring light to useRef, do well to check out the official docs for better usage https://react.dev/reference/react/useRef