Hygraph is a GraphQL-native headless content management system (CMS) that enables businesses to unify data and deliver content efficiently across digital experiences. It leverages content federation and a scalable architecture to reduce developer reliance, modernize tech stacks, and streamline workflows. Learn more at Hygraph Product Page.
What are the key features and benefits of Hygraph?
Hygraph offers GraphQL-native architecture, content federation, scalability, and optimized content delivery performance. Benefits include faster speed-to-market, control at scale, lower total cost of ownership, and improved user experience. For a full list of features, visit Hygraph Features.
Does Hygraph provide an API for developers?
Yes, Hygraph provides a powerful GraphQL API for efficient content fetching and management. Developers can access the API reference at Hygraph API Reference.
What integrations does Hygraph support?
Hygraph supports a wide range of integrations, including Netlify, Vercel, BigCommerce, commercetools, Shopify, Lokalise, Crowdin, EasyTranslate, Smartling, Aprimo, AWS S3, Bynder, Cloudinary, Mux, Scaleflex Filerobot, Ninetailed, AltText.ai, Adminix, and Plasmic. For a full list, visit Hygraph Integrations.
How does Hygraph optimize content delivery performance?
Hygraph emphasizes rapid content distribution and responsiveness, which improves user experience, engagement, and search engine rankings. Optimized delivery reduces bounce rates and increases conversions. More details are available at this page.
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 Hygraph 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. For more details, visit Hygraph Security Features.
How does Hygraph protect sensitive data?
Hygraph provides SSO integrations, audit logs, encryption at rest and in transit, and sandbox environments to safeguard sensitive data and meet regulatory standards. More information is available at Hygraph Security Features.
Use Cases & Customer Success
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. It serves modern software companies, enterprises seeking to modernize, and brands aiming to scale, improve development velocity, or re-platform from legacy solutions.
What industries are represented in Hygraph's case studies?
Hygraph's case studies span 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. Explore more at Hygraph Case Studies.
Can you share specific customer success stories 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. More stories are available at Hygraph Customer Stories.
Who are some of Hygraph's customers?
Hygraph is trusted by Sennheiser, HolidayCheck, Ancestry, Samsung, Dr. Oetker, Epic Games, Bandai Namco, Gamescom, Leo Vegas, and Clayton Homes. For more, visit Hygraph Case Studies.
Pain Points & Solutions
What problems does Hygraph solve?
Hygraph addresses operational pains (developer reliance for content updates, legacy tech stacks, global team conflicts, clunky content creation), financial pains (high costs, slow speed-to-market, expensive maintenance, scalability challenges), and technical pains (boilerplate code, overwhelming queries, evolving schemas, cache and OpenID integration issues). For details, see Hygraph Product Page.
How does Hygraph solve these pain points?
Hygraph provides an intuitive interface for non-technical users, modernizes outdated systems with GraphQL-native architecture, ensures consistent branding via content federation, and streamlines workflows to reduce costs and accelerate speed-to-market. Technical solutions include simplified development, streamlined query management, and robust integration support. See Hygraph Product Page for more.
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, speed to market, maintenance costs, scalability metrics, and performance during peak usage. For more, visit Hygraph Blog on CMS KPIs.
Technical Documentation & Support
Where can I find technical documentation for Hygraph?
Comprehensive technical documentation is available at Hygraph Documentation, covering setup, API usage, integrations, and deployment.
What support and training 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 documentation, video tutorials, webinars, and a community Slack channel. For more, visit Hygraph Contact Page.
How easy is it to get started with Hygraph?
Hygraph is designed for quick onboarding, even for non-technical users. For example, Top Villas launched a new project in just 2 months. Users can sign up for a free account and access onboarding guides and documentation at Hygraph Documentation.
Competition & Differentiation
How does Hygraph differentiate itself from other CMS platforms?
Hygraph stands out with its GraphQL-native architecture, content federation, and scalability. It empowers non-technical users, modernizes legacy systems, and streamlines workflows, offering cost-effective solutions and rapid speed-to-market. For more, visit Hygraph Product Page.
React useCallback() Guide & Developer Resources
What is React's useCallback() Hook and when should I use it?
The useCallback() Hook in React memoizes callback functions to prevent unnecessary re-renders, especially when passing functions as props to child components. Use it for optimizing performance in lists, as dependencies in useEffect, with custom Hooks, and to prevent stale closures. For a complete guide, visit React useCallback() - A complete guide.
How does useCallback() differ from useMemo() in React?
useCallback() memoizes functions, while useMemo() memoizes computed values. useCallback() is typically used for optimizing child component re-renders and as dependencies in Hooks, whereas useMemo() is used for expensive calculations and creating stable objects. See the comparison table in the guide.
Where can I find practical examples of using useCallback()?
Practical examples, including e-commerce scenarios like adding items to favorites and cart, are available in the React useCallback() guide. You can also access the code on GitHub.
Who authored the React useCallback() guide?
The guide was written by Motunrayo Moronfolu, Senior Frontend Engineer and Technical Writer at Hygraph. Published on November 7, 2024.
Blog & Community
Where can I find the Hygraph blog and developer resources?
The Hygraph Blog provides developer tutorials, product updates, and guides to content modeling. Visit Hygraph Blog for news and insights.
How can I stay updated with Hygraph releases and industry news?
Sign up for the Hygraph newsletter to receive updates on releases and industry news. You can subscribe via the blog or main website.
Prevent unnecessary re-renders with React useCallback(). Learn the ins and outs of this powerful Hook and when and how to use it effectively.
Written by Motunrayo
on Nov 07, 2024
Performance optimization is crucial for creating a smoother user experience in modern web development. React, a popular JavaScript library for building user interfaces, provides several Hooks to help developers manage state and side effects efficiently. One such Hook is useCallback(), which plays a vital role in optimizing functional components by memoizing callback functions.
Whether you are a new React developer or someone looking to get more knowledge, this guide will provide you with insights about useCallback(), including its syntax, usage, common use cases, and best practices. We will also compare it with another Hook, useMemo().
Before explaining useCallback(), let’s start by understanding callback functions. In JavaScript, a callback function is a function that is passed as an argument to another function and is executed after some event or action has occurred.
Callback functions work the same way in the React context as in JavaScript, with the addition of being passed as props to child components. This allows children components to communicate with the parent component, enabling a flow of data and actions up the component tree.
Callback functions are an integral part of React apps as they perform activities like asynchronous operations (e.g., network requests) or handle events (e.g., clicks, form submissions, or other user interactions). For example, a button's onClick event handler may be defined as a callback function that updates the state of a React component or performs some action when the button is clicked. Like so:
constMyComponent=()=>{
const[count, setCount]=useState(0);
consthandleClick=()=>{
setCount(count +1);
};
return(
<button onClick={handleClick}>
Click me:{count}
</button>
);
};
In this example, handleClick is a callback function that increments the count state whenever the button is clicked.
Looking at this example, callback functions seem really handy and do what we need them to do. So why is there a need for useCallback()? That is because callback functions are not optimal in all cases, as we will explore in the next section.
Despite the usefulness of callback functions in React development, especially in handling events and interactions, they can lead to performance issues if not handled properly. The main problem stems from how React handles component re-rendering and how JavaScript treats functions as objects.
Let’s consider some common problems associated with callback functions in React:
Unnecessary re-renders
Functions are considered objects in JavaScript; as a result, every time a component renders or re-renders, any function inside that component is recreated as a new function object. This means that even if the function's logic remains exactly the same, React treats it as a new entity every time.
In this example, every time count changes and ParentComponent re-renders, a new handleClick function is created. From React's perspective, this new function is different from the current render of the previous one, even though its functionality hasn't changed.
Prop comparison and child re-renders
When a new function is created and passed as a prop, React sees this as a prop change. This can trigger the parent component to re-render the child component if the child is using optimization techniques like React.memo() or PureComponent. For example:
Even with React.memo, which is designed to prevent unnecessary re-renders, the ChildComponent will re-render every time ParentComponent renders because it receives a "new" onClick prop each time.
Stale closures
Callback functions can sometimes capture outdated values from their previous value, leading to bugs that are difficult to track and fix.
In this counter component, the interval callback will always log 0 because it captures the initial value of count.
These problems lead to performance implications such as:
Cascading re-renders: In a deeply nested component tree, unnecessary re-renders can cascade down, causing significant performance overhead.
Unnecessary computations: Each re-render involves React's reconciliation process, which can be computationally expensive, especially for complex React components.
Increased memory usage: Creating new function instances repeatedly can lead to increased memory consumption over time.
These problems highlight the need for a way to manage callback functions in React applications. The useCallback() is designed to address these, and we will explore it in detail in the upcoming sections.
useCallback() is a part of the built-in React Hooks that optimizes the performance of React applications by preventing unnecessary re-renders of components. It achieves this through memoizing callback functions, ensuring that they are only recreated when the dependency array changes.
Syntax and parameters
The useCallback() syntax looks like so:
const memoizedCallback =useCallback(()=>{
// Your callback logic here
},[dependency1, dependency2,...]);
The useCallback() Hook takes two arguments:
Callback function: This is the first argument, and it represents the function to memorize (remember).
Dependency array: This second argument is an array of dependencies that determine when the callback function should be recreated. If any value in this array changes between renders, the callback function is recreated.
How useCallback() works
After adding useCallback(), React will memoize the provided function instance between re-renders. Here's what happens:
On the initial render, React creates the function and returns it.
On subsequent renders, React will:
a. Check if any values in the dependency array have changed.
b. If none have changed, it returns the same function instance from the previous render.
c. If any have changed, it creates a new function instance and returns that.
This means that as long as the dependencies don't change, the exact same function instance is returned every time the component re-renders.
Let’s consider this example showing how useCallback() works:
functionParentComponent(){
const[count, setCount]=useState(0);
const increment =useCallback(()=>{
setCount((c)=> c +1);
},[]);// Empty dependency array means this function never changes
Here are some scenarios where using useCallback() is particularly beneficial:
Optimizing performance in lists: When rendering a list of items, you might need to pass a callback to each item. Using useCallback() ensures that the same callback instance is passed to each item, preventing unnecessary re-renders.
When a callback is a dependency in useEffect(): Use useCallback() when the callback is a dependency in a useEffect Hook to prevent the effect from running unnecessarily.
When working with custom Hooks: Use useCallback() to ensure consistent function references when creating custom Hooks that return callback functions, especially if these other functions will be used as dependencies in effects.
Preventing stale closures: When a callback function depends on state or props, using useCallback() helps to ensure the function always has the latest values.
Passing callbacks to child components: If the function references change, the child components may re-render unnecessarily. useCallback() helps prevent this by memoizing the function, ensuring it only changes when its dependencies change.
Everything discussed is of little use if we cannot apply the knowledge to real-world applications. As a result, we will now explore using useCallback() in an e-commerce application. For this use case, we will focus on two functionalities:
Adding items to "Favorites"
Adding items to "Cart"
To do this, we will use Hygraph, a GraphQL-native headless content management system. Hygraph simplifies the development process by providing content management features while allowing developers to focus on building.
Create a React App
Set up a new React application using Vite by running the following command:
npm create vite@latest
Select React as the framework and complete the installation process. Additionally, install TailwindCSS for styling.
Start the development server using:
npm run dev
Now, check the terminal for the port the application is running on.
Setting up the Hygraph project
First, sign up for a free-forever developer account if you haven't already.
To use Hygraph in the React application, follow these steps:
Clone the project: Clone this Hygraph eCommerce starter project to quickly set up a storefront. Once cloned, open the project.
Configure API access: In the Hygraph project, navigate to Project Settings > API Access > Public Content API. Configure the Public Content API permissions to allow read requests without authentication. Click “Yes, initialize defaults” to add the necessary permissions for the High Performance Content API.
Set environment variable: Locate the “High Performance Content API” and copy the URL. In the root folder of the React application, create a .env file and add the URL. Like so:
VITE_HYGRAPH_HIGH_PERFORMANCE_ENDPOINT=YOUR_URL
Substitute “YOUR_URL” with the appropriate URL.
Before working on the React app, explore Hygraph to understand the available content.
Navigate to Hygraph’s API playground and run the query below to fetch product data, like so:
query GetProducts{
products {
images {
id
url
}
name
price
id
}
}
This query retrieves product information accessible via the “Content” view. Now, let’s fetch and display the product data in our React application.
Fetching data from Hygraph
Navigate to the project terminal and install the GraphQL client for fetching data:
npm add graphql-request
Open App.js and add the code below to fetch and display products:
The code above fetches data from Hygraph using the High Performance Content API. We also used the [useState](https://hygraph.com/blog/usestate-react) Hook, which manages the product data state, while the useEffect handles the data fetching.
At this point, we should have a screen that looks like this:
Next, let’s add a feature to mark products as “favorites” to demonstrate the usefulness of useCallback().
In this case, we are using the heart icon to demonstrate the favorite in the UI.
Next, we will add a state:
const[favorites, setFavorites]=useState({});
This initializes the state variable favorites as an empty object and provides a function setFavorites to update the state. This function object allows toggling between two states, such as “favorited” or “not favorited”.
Next, we will declare the useCallback() :
const handleFavorite =useCallback((id)=>{
setFavorites((prevFavorites)=>({
...prevFavorites,
[id]:!prevFavorites[id],
}));
},[]);
Here, we achieved the following:
We wrapped the handleFavorite function in a useCallback() to memoize it to prevent unnecessary re-creations on re-renders. This is especially beneficial for performance should the product item get larger applications with many products.
The function also toggled the favorite status of a product by updating the favorites state.
Now, we will complete this by adding the code below the “Price”:
When a user clicks the button, it triggers the handleFavorite function declared earlier with the product's ID.
The color of the heart icon changes based on the favorite status stored in the favorites state object.
Now, we should be able to see a favorite icon in the UI for each product.
Using the useCallback() Hook here to toggle favorites on each product helps prevent unnecessary re-creations of the handleFavorite function on re-renders. This optimization is crucial in scenarios with many items. Now let us add the “add to cart functionality”.
Implementing “add to cart” feature
First, update the FontAwesome imports to include shopping cart icons:
Using useCallback() in this application helps improve performance as the number of products and interactions increases. It ensures that functions handling the internal state updates are not recreated unnecessarily.
In React, both useCallback() and useMemo() are Hooks that optimize performance by memoizing values and functions, but they serve different purposes and are used in different scenarios.
With a syntax that looks like the below, useMemo() accepts two arguments (similar to useCallback()):
a function to calculate
a dependency array
const memoizedValue =useMemo(
()=>computeExpensiveValue(a, b),
[a, b],// Dependency array
);
When comparing useCallback() with useMemo(), the differences are best based on what they memoize, return, and their use cases, as this sometimes shows the mistaken line between the two Hooks.
Considerations
useCallback()
useMemo()
What they memoize
Memoizes a callback function
Memoizes computed value
Return value
Returns a memoized callback function
Returns a memoized value (which can be a new value of any type)
Use
Typically for optimizing child component re-renders and in dependency arrays of other Hooks
For expensive, complex calculations and creating objects that should remain stable
console.log(`Expensive value for a=${a} and b=${b}: ${expensiveValue}`);
returnnull;
};
exportdefaultApp;
In this example, useMemo() memoizes the result of computeExpensiveValue(). The computation will only re-run if a or b changes, avoiding unnecessary recalculations on every render. This is in contrast to useCallback(), where the function itself would be memoized, but the expensive computation would still run every time the function is called, even if a and b haven't changed.
Now that we have explored the difference between useCallback() and useMemo(), let’s consider when it is best to use useCallback().
Like any other Hook, useCallback() should only be used at the top level of the component and outside of any loop or condition.
Pair useCallback() with [React.memo()](https://hygraph.com/blog/react-memo) for child components to prevent unnecessary re-renders when the callback function's reference hasn't changed.
The dependency array is crucial, and omitting necessary dependencies can cause bugs. In the dependency array, include all values from the component scope that the callback function depends on.
It goes without saying that useCallback() should only be used if and when necessary. As such, only use useCallback() when the performance benefit is obvious.
This guide provides an overview of the React useCallback Hook, from the problem it solves to its use cases and best practices for its implementation.
Join the Hygraph developer workspace to discover exciting innovations and connect with other developers. It’s also a great place to interact with the Hygraph team, share insights, and expand your skills.
Blog Author
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.