Frequently Asked Questions

Product Information & Technical Guides

What is React's useRef() Hook and how does it work?

The useRef() Hook is a built-in React feature that persists values between component re-renders. It returns a plain JavaScript object with a single property, current, which can store any mutable value (numbers, strings, objects, DOM elements, etc.). Unlike state variables managed by useState, updating current does not trigger a re-render. This makes useRef() ideal for scenarios where you need to store data that doesn't directly affect the UI but is essential for component behavior. Read the full guide.

What are the main use cases for useRef() in React?

Key use cases for useRef() include accessing DOM elements (e.g., focusing input fields), tracking previous values (for undo functionality or custom Hooks), managing timers and intervals, and building custom Hooks that maintain internal state between renders. useRef() is also useful for caching results of expensive computations to optimize performance. See examples in the guide.

How does useRef() compare to useState() in React?

While both useRef() and useState() store values in React components, they serve different purposes. useRef() stores mutable values that persist across renders but do not trigger re-renders when updated. useState() manages UI state and triggers a re-render when updated. Use useRef() for values that don't affect rendering, and useState() for data that should update the UI. Learn more.

What are the drawbacks of using useRef()?

Drawbacks of useRef() include manual management (changes to .current do not trigger re-renders), potential memory leaks if refs are not cleaned up, overuse leading to complex code, debugging challenges, and limitations when updating arrays or objects (individual property changes won't trigger UI updates). To mitigate these, use useRef() only when necessary, clean up refs properly, and prefer state for UI-related data. Read more.

How does useRef() differ from createRef() in React?

useRef() is designed for functional components and persists the same ref object across renders, while createRef() is used in class components and creates a new ref object on every re-render. useRef() is more flexible and recommended for modern React development. See comparison table.

How can useRef() be used with content fetched from Hygraph?

When integrating Hygraph (a GraphQL-native headless CMS) with React, useRef() can be used to store references to elements within dynamically fetched content, such as images or content blocks. This enables features like lazy loading, smooth scrolling, and interactive components. useRef() also helps optimize data fetching by caching results, reducing load on the CMS and improving performance. Learn about Hygraph's React integration.

Features & Capabilities

What features does Hygraph offer?

Hygraph provides a GraphQL-native architecture, content federation, scalability, and optimized content delivery performance. It supports rapid content distribution, reduces bounce rates, and increases conversions. Hygraph also offers a wide range of integrations (Netlify, Vercel, Shopify, BigCommerce, AWS S3, Cloudinary, and more), a powerful GraphQL API, and enterprise-grade security features. See all features.

What integrations are available with Hygraph?

Hygraph integrates with hosting and deployment platforms (Netlify, Vercel), eCommerce solutions (BigCommerce, commercetools, Shopify), localization tools (Lokalise, Crowdin, EasyTranslate, Smartling), digital asset management (Aprimo, AWS S3, Bynder, Cloudinary, Mux, Scaleflex Filerobot), personalization and AB testing (Ninetailed), AI tools (AltText.ai), and more. See the full list.

Does Hygraph provide an API?

Yes, Hygraph offers a powerful GraphQL API for efficient content fetching and management. Explore the API reference.

What technical documentation is available for Hygraph?

Hygraph provides comprehensive technical documentation covering setup, API usage, integrations, and deployment. The documentation has been revamped for a cleaner look and includes API references and guides in one place. Access Hygraph Documentation.

Pricing & Plans

What is Hygraph's pricing model?

Hygraph offers a free forever Hobby plan, a Growth plan starting at $199/month, and custom Enterprise plans. For full details, visit the pricing page.

Security & Compliance

What security and compliance certifications does Hygraph have?

Hygraph is SOC 2 Type 2 compliant, ISO 27001 certified, and GDPR compliant. These certifications ensure enterprise-grade security and data protection. Hygraph also provides SSO integrations, audit logs, encryption at rest and in transit, and sandbox environments. Learn more about Hygraph Security Features.

Use Cases & Benefits

Who can benefit from using Hygraph?

Hygraph is ideal for developers, IT decision-makers, content creators, project/program managers, agencies, solution partners, and technology partners. Companies that benefit most include modern software companies, enterprises seeking to modernize their tech stack, and brands aiming to scale globally, improve development velocity, or re-platform from traditional solutions.

What problems does Hygraph solve?

Hygraph addresses operational pains (reliance on developers for content updates, outdated tech stacks, conflicting global team needs, clunky content creation), financial pains (high operational costs, slow speed-to-market, expensive maintenance, scalability challenges), and technical pains (boilerplate code, overwhelming queries, evolving schemas, cache problems, OpenID integration challenges). See how Hygraph solves these problems.

What business impact can customers expect from using Hygraph?

Customers can expect significant time savings, streamlined workflows, ease of use, faster speed-to-market, and enhanced customer experience through consistent and scalable content delivery. These benefits help businesses modernize their tech stack and achieve operational efficiency.

Can you share specific case studies or success stories of customers using Hygraph?

Yes. Komax achieved a 3X faster time to market, Autoweb saw a 20% increase in website monetization, Samsung improved customer engagement with a scalable platform, and Dr. Oetker enhanced their digital experience using MACH architecture. Explore more success stories.

What industries are represented in Hygraph's case studies?

Hygraph's case studies cover industries such as food and beverage (Dr. Oetker), consumer electronics (Samsung), automotive (AutoWeb), healthcare (Vision Healthcare), travel and hospitality (HolidayCheck), media and publishing, eCommerce, SaaS (Bellhop), marketplace, education technology, and wellness and fitness. See all case studies.

Who are some of Hygraph's customers?

Hygraph is trusted by companies such as Sennheiser, HolidayCheck, Ancestry, Samsung, Dr. Oetker, Epic Games, Bandai Namco, Gamescom, Leo Vegas, and Clayton Homes. See customer stories.

Support & Implementation

How easy is it to get started with Hygraph?

Hygraph is designed for easy onboarding, even for non-technical users. Customers can sign up for a free-forever account and access documentation, video tutorials, and onboarding guides. For example, Top Villas launched a new project in just 2 months from initial contact. Get started with Hygraph.

What customer service and support does Hygraph offer?

Hygraph provides 24/7 support via chat, email, and phone. Enterprise customers receive dedicated onboarding and expert guidance. All users have access to detailed documentation, video tutorials, and a community Slack channel. Contact Hygraph Support.

What training and technical support is available for Hygraph?

Hygraph offers onboarding sessions for enterprise customers, 24/7 support, training resources (video tutorials, documentation, webinars), and Customer Success Managers to guide users through adoption. Learn more about support.

How does Hygraph handle maintenance, upgrades, and troubleshooting?

Hygraph provides 24/7 support for maintenance, upgrades, and troubleshooting. Enterprise customers receive dedicated onboarding and expert guidance, while all users can access documentation and the community Slack channel for additional help.

Performance & Metrics

How does Hygraph optimize content delivery performance?

Hygraph emphasizes optimized content delivery performance, ensuring rapid distribution and responsiveness. This reduces bounce rates, increases conversions, and positively impacts user experience and search engine rankings. Learn more about performance.

What KPIs and metrics are associated with the pain points Hygraph solves?

KPIs include time saved on content updates, system uptime, consistency across regions, user satisfaction scores, reduction in operational costs, ROI, time to market, maintenance costs, scalability metrics, and performance during peak usage. See more on CMS KPIs.

Competition & Differentiation

How does Hygraph differentiate itself from other CMS platforms?

Hygraph stands out with its GraphQL-native architecture, content federation, scalability, and ease of use. It empowers non-technical users, modernizes legacy tech stacks, supports global teams, and streamlines workflows. Hygraph also offers cost-effective solutions, rapid speed-to-market, and robust technical capabilities. See product differentiation.

Why should a customer choose Hygraph over alternatives?

Customers should choose Hygraph for its unique GraphQL-native architecture, content federation, scalability, and ability to create impactful digital experiences while reducing costs and improving efficiency. Learn why Hygraph is a top choice.

Blog & Resources

Where can I find the Hygraph blog and developer guides?

The Hygraph Blog provides the latest updates, developer tutorials, and essential guides to content modeling. Visit the Hygraph Blog for news and insights.

Who authored the 'React useRef() - A complete guide' blog post?

The blog post was written by Motunrayo Moronfolu, Senior Frontend Engineer and Technical Writer at Hygraph. Read the post.

What does the blog post encourage readers to do?

The blog post encourages readers to sign up for the newsletter to stay informed about releases and industry news.

Webinar Event: How to Avoid Personalization Tech Traps

React useRef() - A complete guide

Learn how to use React's useRef Hook for DOM manipulation, performance optimization, and more in this in-depth guide.
Motunrayo Moronfolu

Written by Motunrayo 

Dec 09, 2024
React useRef() - A complete guide

The useRef Hook is a versatile tool, often overlooked but crucial for managing references, optimizing performance, and interacting directly with the Document Object Model (DOM). While it might not be as widely discussed as useState or useEffect, it plays a pivotal role in many React applications.

This guide will discuss the useRef Hook, its use cases, practical applications, and drawbacks. By the end, you'll be well equipped to leverage its full potential, unlocking new levels of efficiency and control in your React projects.

#What is useRef()?

What is useRef()?

The useRef() Hook is a built-in React feature that persists values between component re-renders. Unlike state variables managed by useState, values stored in a ref object remain unchanged across renders, making it ideal for scenarios where data doesn't directly affect the UI but is essential for the component's behavior.

#How does React useRef() work?

When React encounters a useRef() Hook, it returns a plain JavaScript object with a single property: current. This current property stores mutable values, which can be of any type, from simple values like numbers and strings to complex objects, functions, or even references to DOM elements.

How does React useRef() work?

React assigns the initial value you define to the current property of the returned reference. React will set the value of the useRef to undefined if you don't provide an initial value. Importantly, you can update this current value directly without triggering a re-render of the component. This can be seen in the snippet below:

import { useRef } from "react";
function MyComponent() {
const reference = useRef(true);
console.log(reference.current); // true
}

Also, the returned reference object is mutable. You can update the current value directly, as shown in the snippet below.

import { useRef } from "react";
function MyComponent() {
const reference = useRef(true);
const handleUpdate = () => {
reference.current = !reference.current;
};
console.log(reference.current); // true
return <button onClick={handleUpdate}>Update</button>;
}

Clicking the “Update” button changes the reference.current value from true to false and the other way around.

#Use cases of useRef() React Hook

Beyond its ability to persist values, the useRef() Hook has several vital roles in React applications:

Accessing DOM elements

Imagine a login page where users need to enter their username and password. To enhance the user experience, you can automatically direct their focus to the username field as soon as the page loads.

To achieve this, use the useRef 's capacity to access rendered DOM elements. This feature returns the referenced DOM element and its properties, providing room for direct manipulations.

import { useRef, useEffect } from “react”
function Login() {
const usernameRef = useRef(null)
useEffect(() => {
usernameRef.current.focus()
}, [])
return (
<>
<form>
<input type="text" ref={usernameRef} />
</form>
</>
)
}

The above snippet shows a Login component that renders a form with an input field for the user’s username. Also, it defines a username reference with the useRef Hook, which the focus() method is called on. This is executed inside a useEffect Hook, so it runs immediately after the UI finishes loading.

Tracking previous values

By storing the previous value of the input element as a state variable in a ref, you can monitor changes and address them accordingly. This technique is useful for implementing "undo" functionality, creating custom Hooks that need to compare previous and current values, or optimizing performance by preventing unnecessary calculations.

import { useState, useRef, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const previousCountRef = useRef(count); // Store previous count in a ref
useEffect(() => {
if (previousCountRef.current !== count) {
console.log('Count changed:', count, '(Previous:', previousCountRef.current, ')');
}
previousCountRef.current = count; // Update the ref
}, [count]); // Run the effect only when count changes
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

In this example, the useRef Hook stores the previous value of the count state variable. Every time the count changes, the useEffect Hook compares the new count to the value stored in the previousCountRef and logs a message to the console if they differ. This way, you can track how the count value evolves over time.

Managing timers and intervals

The useRef simplifies the management of timers and intervals within your components. You can store the timer's ID in a ref, allowing you to start, stop, or reset it as needed without triggering unnecessary re-renders.

import { useState, useRef, useEffect } from 'react';
function myTimer() {
const [seconds, setSeconds] = useState(0);
const timerRef = useRef(null); // Ref to store the timer ID
const startTimer = () => {
timerRef.current = setInterval(() => {
setSeconds((prevSeconds) => prevSeconds + 1);
}, 1000); // Update every second
};
const stopTimer = () => {
clearInterval(timerRef.current);
};
const resetTimer = () => {
clearInterval(timerRef.current);
setSeconds(0);
};
// Cleanup function to clear the interval when the component unmounts
useEffect(() => {
return () => clearInterval(timerRef.current);
}, []);
return (
<div>
<p>Time elapsed: {seconds} seconds</p>
<button onClick={startTimer}>Start</button>
<button onClick={stopTimer}>Stop</button>
<button onClick={resetTimer}>Reset</button>
</div>
);
}

In this example, a timer component was created using the useState and useRef Hooks. The useState Hook manages the seconds variable, which keeps track of the elapsed time. Meanwhile, useRef stores a reference to the interval ID (timerRef), which is responsible for updating the seconds every 1000 milliseconds (1 second).

The functions startTimer, stopTimer, and resetTimer control the timer's behavior. startTimer starts the interval, stopTimer stops it, and resetTimer resets the elapsed time to zero.

Building custom Hooks

When creating custom Hooks that need to maintain an internal state between renders, useRef becomes an invaluable asset. It enables you to store and update data privately within the Hook, promoting reusability and encapsulation of complex logic.

Imagine having multiple components that are required to maintain their previous state. It will appear too tedious to write this logic individually for every component. To avoid this, create a custom Hook using the useRef Hook as follows:

First, create a Hooks folder and a file usePreviousState.js, then add the following snippet:

import { useRef, useEffect } from "react";
export default function usePreviousState(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}

In the snippet above, a useRef instance was created, then on every page re-render, assign the value passed to the usePreviousState Hook to the ref.current. Finally, return the value of the ref.current.

To illustrate the custom Hook's utility, let’s revisit the 'tracking previous values' scenario

import { useState, usePreviousState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const previousCount = usePreviousState(count); // Store previous count in a custom Hook
useEffect(() => {
if (previousCount !== count) {
console.log('Count changed:', count, '(Previous:', previousCount, ')');
}
previousCount = count; // Update the previous state
}, [count]); // Run the effect only when count changes
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

In the snippet above, all instances of the initial useRef were replaced with the newly created custom Hook. This shows that creating a custom Hook makes it possible to reuse complex logic.

#Optimizing performance

Beyond its DOM manipulation capabilities, useRef shines as a performance enhancer. Imagine you have a computationally intensive task within your component, such as filtering a dataset or performing calculations, re-executing these operations on every render would be wasteful.

Storing values of these calculations within a ref variable using useRef can avoid unnecessary re-computations. Since refs persist across renders without triggering updates, the calculated value remains accessible and doesn't need to be recalculated unless the underlying data changes. Let's look at the example shown below:

import { useState, useRef, useMemo } from "react";
export default function calculationComponent() {
const [inputNumber, setInputNumber] = useState(10); // Initial Calculation number
const calculateResult = useRef(null); // Ref to store the calculated result
const calculateFib = (n) => {
if (n <= 1) return n;
return calculateFib(n - 1) + calculateFib(n - 2);
};
// Memoize the calculation using useMemo
const memoizedCal = useMemo(() => {
if (
calculateResult.current &&
calculateResult.current.input === inputNumber
) {
// If the input hasn't changed, reuse the cached result
return calculateResult.current.result;
} else {
// Calculate the result and store it in the ref
const result = calculateFib(inputNumber);
calculateResult.current = { input: inputNumber, result };
return result;
}
}, [inputNumber]);
return (
<div>
<input
type="number"
value={inputNumber}
onChange={(e) => setInputNumber(parseInt(e.target.value, 10))}
/>
<p>
Result of {inputNumber} is: {memoizedCal}
</p>
</div>
);
}

In the snippet above, the useRef Hook, named calculateResult, is employed to optimize performance by caching the results of a computationally expensive calculation like the Fibonacci sequence. The calculateResult.current property stores both the input number and the calculated result, allowing for comparison on subsequent renders.

The useMemo Hook is used to memoize the calculation. It checks if the input number (inputNumber) has changed since the last render. If not, it returns the cached result from calculateResult.current, avoiding redundant computation. If the input number changes, the Fibonacci calculation is performed, and the result is stored in calculateResult.current for future reuse.

This memoization strategy improves the component's performance by preventing recalculations whenever the component re-renders due to unrelated state changes. While useRef offers performance benefits, knowing its potential drawbacks is essential.

#Drawbacks of useRef Hook

  • Manual management: Unlike state variables managed with useState or useReducer, changes to the .current property of a ref attribute do not automatically trigger re-renders of your component. This means you need to manage updates and trigger re-renders manually when necessary and can add extra complexity to your code.
  • Potential memory leaks: If you're not careful, you can create dangling refs. This happens when a ref is still holding onto a reference to a DOM element or other object that has already been unmounted or removed from the DOM, leading to memory leaks.
  • Overuse: While refs are helpful in certain scenarios, overusing them can lead to a more complex and less maintainable codebase.
  • Debugging challenges: Since changes to refs don't trigger re-renders, debugging issues related to refs can sometimes be more complicated than debugging state-related problems.
  • Not suitable for array or object updates: Although you can store arrays or objects in a ref, updating individual properties or elements within them won't trigger re-renders. You'll need to manually update the entire array or object and trigger a re-render if you want those changes to be reflected in the UI. This can require more work than using state for mutable value structures.

To mitigate these drawbacks

  • Use the useRef when necessary and prioritize managing UI-related data with state (useState or useReducer) as it automatically triggers re-renders.
  • Always ensure proper cleanup of refs when components are removed from the DOM to prevent memory leaks.
  • Leverage debugging tools like React DevTools to track ref values and their impact if your code becomes overly reliant on refs.
  • Consider alternative approaches like lifting the state up or using context to streamline state management and component communication.

#useRef vs. useState Hook

While both useRef and useState store values in React components, they serve different purposes and behave differently. Let's look at these Hooks, exploring their characteristics and how they contribute to state management in a React component.

Feature useRef useState
Mutable Yes, the .current property can be changed directly No, state updates must be done through the setter function (e.g., setCount)
Persistence a**cross r**enders Yes, the value persists for the lifetime of the component No, the value is reset on each re-render
Triggers r**e-render** No, updating the .current property does not cause a re-render Yes, updating state using the setter function triggers a re-render of the component
Common u**se c**ases Accessing DOM elements, storing previous values, managing timers/intervals, storing references Managing UI state, storing data that directly affects the component's rendering

#useRef Hook vs createRef function

Before the Hooks era, React used createRef() for refs in their application. Let's break down their key distinctions when it comes to managing refs in React applications:

Feature useRef Hook createRef Function
Component t**ype** Exclusively used in functional components (introduced in React 16.8) Designed for class components (pre-Hooks era)
Initial v**alue** Takes an optional initial value, assigned to ref.current (defaults to undefined) No initial value, ref.current is initially null
Re-renders Returns the same ref object on each re-render, maintaining its value Creates a new ref object on every re-render, losing the previous value
Persistence Value persists for the entire component lifecycle Value is lost on re-renders unless explicitly stored in a class component's instance variable
Flexibility More flexible in functional components due to its persistence Less flexible, requires additional state management for persistence in class components

If you're using functional components with React Hooks, useRef is the way to go. But if you're working with legacy class components, createRef is your best option.

However, consider refactoring to functional components and the useRef Hook for a more modern and maintainable approach. Next, let's discuss the useRef Hook in data fetched from content management systems.

useRef Hook in dynamic content fetched from CMSs

The useRef Hook, although not inherently tied to Content Management Systems (CMS), plays a crucial role in enhancing user interactions with dynamically fetched content from platforms like Hygraph, a GraphQL-Native Headless Content Management, and Federation System.

By storing references to specific elements within the fetched data, such as images or content blocks, developers can implement features like lazy loading, smooth scrolling, or interactive components.

Furthermore, useRef is valuable in optimizing data fetching from CMSs by caching results, especially for complex queries or large datasets. This caching mechanism reduces the load on the CMS and improves the application's performance as it avoids redundant data fetching operations.

#Summing it up

While often overlooked, the useRef Hook is a powerful asset in a React developer's toolkit. It excels in managing references, optimizing performance, and enabling seamless interactions with DOM elements.

Understanding its capabilities and appropriate use cases allows developers to create more efficient, maintainable, and interactive React applications. Whether you're building complex animations, managing timers, or integrating with headless CMS platforms like Hygraph to optimize content delivery, useRef proves its value repeatedly.

Ready to explore the power of Hygraph? Sign up for a free-forever developer account and experience the seamless integration of Hygraph with React and its powerful Hook like useRef.

Blog Author

Motunrayo Moronfolu

Motunrayo Moronfolu

Technical writer

Motunrayo Moronfolu is a Senior Frontend Engineer and Technical writer passionate about building and writing about great user experiences.

Share with others

Sign up for our newsletter!

Be the first to know about releases and industry news and insights.