0% found this document useful (0 votes)
9 views39 pages

React Hooks_ The only guide you’ll ever need _ Hygraph

The document is a comprehensive guide on React Hooks, detailing their purpose, rules, and various types such as useState, useEffect, and useReducer, among others. It emphasizes the advantages of using Hooks for managing state and lifecycle features in functional components, enhancing code quality and developer experience. Practical examples and code snippets are provided to illustrate the implementation of these Hooks in real-world scenarios.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views39 pages

React Hooks_ The only guide you’ll ever need _ Hygraph

The document is a comprehensive guide on React Hooks, detailing their purpose, rules, and various types such as useState, useEffect, and useReducer, among others. It emphasizes the advantages of using Hooks for managing state and lifecycle features in functional components, enhancing code quality and developer experience. Practical examples and code snippets are provided to illustrate the implementation of these Hooks in real-world scenarios.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

Easily restore your project to a previous version with our new Instant One-click Backup Recovery

Blog Developer tutorials React Hooks: The only guide you’ll ever need

Frontend React

React Hooks: The only


guide you’ll ever need
Understand React Hooks, such as useState,
useEffect, useReducer, and more, with practical
examples and tips for efficient React development.

Written by Chidi on Aug 19, 2024

https://hygraph.com/blog/react-hooks 1/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

In this post

Rules of React Hooks

The useState Hook

The useEffect Hook

The useReducer Hook

The useCallback Hook

The useMemo Hook

The useContext Hook

The useRef Hook

The useId Hook

The useDeferredValue Hook

The useDebugValue Hook

The useImperativeHandle Hook

The useLayoutEffect Hook

The useInsertionEffect Hook

The useSyncExternalStore

The useTransition Hook

The useOptimistic Hook

The useActionState Hook

Conclusion

React Hooks are powerful features introduced in React 16.8


that let you "Hook into" React state and lifecycle features
from function components.

By eliminating the need for class-based components, Hooks


have brought in a new era of declarative and composable

https://hygraph.com/blog/react-hooks 2/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

React development. They empower you to build more


concise, reusable, and testable components, enhancing
overall code quality and developer experience.

In this blog post, you’ll discover different types of Hooks and


their benefits and drawbacks, and the code examples
provided will help you understand how to use them.

Rules of React Hooks

React Hooks come with two rules that must be followed to


ensure their proper functioning and avoid errors:

1. Call Hooks at the top level: Call Hooks outside loops,


conditions, or nested functions.

2. Call Hooks from Reactfunctions: Only use Hooks within


React function components or custom Hooks.

These rules ensure that the order of Hook calls remain


consistent across renders, preventing React from getting
confused about which state corresponds to which Hook.

https://hygraph.com/blog/react-hooks 3/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

Let's clone this Hygraph project to set up the environment


for discussing the practical applications of some common
Hooks. This will serve as our playground for demonstrating
these Hooks in action. Now, let's get started with the
useState Hook.

The useState Hook

This React Hook allows you to add state to functional


components. It provides a way to store and manage values
that can change over time within your component, triggering
re-renders whenever the state is updated.

Example

function Counter() {
const [count, setCount] = useState(0); // Initial state i

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me<
</div>
);
}

In the code above, the useState Hook creates an array with


the state value ( count ) and a function to update the state
( setCount ). The state has an initial value of 0 , but it could
also be null , an empty array ( [] ), an object, or any value
that suits your needs.

https://hygraph.com/blog/react-hooks 4/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

The useState Hook is best suited for managing state values


and provides an intuitive way to manage states in functional
components. If you call the setCount function with a new
value, your state will be updated, and React will
automatically re-render the component with the updated
state, ensuring that your UI is always up-to-date. Let's
discuss the useEffect Hook next.

The useEffect Hook

The useEffect Hook is a powerful React Hook that allows


functional components to perform side effects. Side effects
are operations that interact with the outside world or have
an impact beyond the component's scope, such as
fetching data from an API, directly updating the DOM,
setting up subscriptions, and so on. Here's a quick
implementation example:

function App() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;

}, [count]); // Dependency array


return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me<
</div>
);
}

The useEffect takes two arguments:

https://hygraph.com/blog/react-hooks 5/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

A function that contains the side effect logic (in this


case, updating the document title)

An optional dependency array (in this case, [count] )

The side effect function is called whenever the component


mounts, whether the dependency array is present or not. It
uses the current value of the count variable to update the
document title.

function App() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
// Cleanup function
return () => {
document.title = 'Default Title';
};
}, [count]); // Dependency array
//Component return() here
}

The cleanup function (returned from the side effect


function) is called when the component is about to
be unmounted or when a new side effect is about to
be executed. In this case, it resets the "React App"
document title.

The dependencies array [] instructs React to execute the


useEffect side effect function only when the values inside it

change between renders, in our case [count] . If no


dependency array is provided, the effect will run after every
render, whether the values changed or not.

https://hygraph.com/blog/react-hooks 6/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

While `useEffect` is a powerful React Hook, it can also


introduce complexity, especially when dealing with multiple
effects, complex dependency arrays, or intricate cleanup
logic. This can make your code harder to reason about and
maintain, which is why there are many nuanced opinions
about it in the React community.

For a more practical implementation of the useEffect and


useState Hooks, let's optimize the Hygraph Next.js project

you cloned earlier. Update the product/[slug]/page.jsx


with the following snippets:

'use client';
import { useState, useEffect } from 'react';
import { GraphQLClient } from 'graphql-request';
import Link from 'next/link';
const hygraph = new GraphQLClient(
'https://api-eu-central-1.hygraph.com/v2/ck8sn5tnf01gc01z
);
const QUERY = `
query ProductPageQuery($slug: String!) {
product(where: { slug: $slug }) {
name
description
price
}
}
https://hygraph.com/blog/react-hooks 7/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

`;
export default function Product({ params }) {
const [product, setProduct] = useState(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const fetchProduct = async () => {
try {
const { product } = await hygraph.request(QUERY, {
setProduct(product);
} catch (error) {
console.error('Error fetching product:', error);
} finally {
setIsLoading(false);
}
};
fetchProduct();
}, [params.slug]); // Fetch only when slug changes
return (
<>
<Link href="/">Home</Link>
{isLoading ? (
<p>Loading...</p>
) : (
<>
<h1>{product.name}</h1>
<p>{product.description}</p>
<p>€{product.price / 100}</p>
</>
)}
</>
);
}

The code has been refactored to utilize React's useState


Hook for managing the product data, and a loading state
(isLoading ) was also added. This enables efficient re-
renders only when necessary and provides a loading
indicator to improve the user experience.

Additionally, the useEffect Hook fetches product data


solely when the component mounts or when the product's
slug changes, preventing redundant API calls. The code also
https://hygraph.com/blog/react-hooks 8/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

includes error handling and query optimization for


robustness and readability.

The useReducer Hook

The useReducer is another React Hook used for state


management in functional components. It's an alternative
Hook like useState when dealing with complex state
management. In cases where your state logic involves
multiple interconnected values or when the next state is
determined by both the previous state and a specific action,
useReducer excels.

This allows for a more structured and centralized approach


to state management, encapsulating complex logic within a
reducer function.

How it works:

The reducer() takes the current state and an action object


as arguments. The action object has a type property (and
can also have a payload). Based on the action.type , the
reducer determines how to update the state and returns the
new state.

The useReducer Hook is then called with the reducer


function and an initial state. Afterwards, it returns an array
with two values:

state : This is the current state managed by the

reducer.

https://hygraph.com/blog/react-hooks 9/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

dispatch : This function triggers state updates by

sending action objects to the reducer.

To update the state, you only need to call the dispatch


function with an action object. The reducer will then listen
to the action and update the state accordingly, causing
React to re-render the corresponding component.

Example

In the example, we will optimize fetching all products with


the useReducer and useEffect Hooks. Still in our Hygraph
project, update the app/page.jsx with the following
code snippets:

"use client"
import { useReducer, useEffect } from 'react';
import { GraphQLClient, gql } from 'graphql-request';
import Link from 'next/link';

const hygraph = new GraphQLClient(


'https://api-eu-central-1.hygraph.com/v2/ck8sn5tnf01gc01z
);

const QUERY = `
{
products {
slug
name
id
}
}
`;

const initialState = {
products: [],
loading: true,
error: null
};

https://hygraph.com/blog/react-hooks 10/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

function reducer(state, action) {


switch (action.type) {
case 'FETCH_SUCCESS':
return { products: action.payload, loading: false, er
case 'FETCH_ERROR':
return { products: [], loading: false, error: action.
default:
return state;
}
}

export function generateMetadata() {


return { title: 'Products' };
}

export default function Page() {


const [state, dispatch] = useReducer(reducer, initialStat

useEffect(() => {
const fetchProducts = async () => {
try {
const { products } = await hygraph.request(QUERY);
dispatch({ type: 'FETCH_SUCCESS', payload: products
} catch (error) {
dispatch({ type: 'FETCH_ERROR', payload: error.mess
}
};

fetchProducts();
}, []);

return (
<div>
<h1>Products</h1>
{state.loading ? (
<p>Loading...</p>
) : state.error ? (
<p>Error: {state.error}</p>
) : (
<ul>
{state.products.map(({ slug, name, id }) => (
<li key={id}>
<Link href={`/products/${slug}`}>{name}</Link
</li>
))}
</ul>
)}

https://hygraph.com/blog/react-hooks 11/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

</div>
);
}

By incorporating useReducer , the code becomes more


organized, the state management is centralized, and error
handling and loading states are explicitly managed.

Another example where useReducer truly shines is when


implementing a shopping cart component. You can employ
the useReducer Hook to manage adding, removing, and
modifying items within the cart. This approach helps
maintain a clean and efficient state structure; however,
useState might be a better alternative for simple state

updates. Next, let's discuss the useCallback Hook.

The useCallback Hook

The useCallback Hook memoizes a callback function to


ensure that it is not recreated on every render unless its
dependencies change. This capability can be crucial
for improving the performance of React applications,
especially when dealing with complex components and
frequent updates.

Here's how it works:

It takes two arguments, a callback function and an array


of dependencies, similar to the useEffect Hook.

On the initial render, useCallback returns the callback


function you passed.

https://hygraph.com/blog/react-hooks 12/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

On subsequent renders, useCallback compares the


dependencies with the previous render's dependencies.

If none of the dependencies have changed, the


useCallback Hook will return the same function.

If any dependency has changed, useCallback returns a


new memoized version of the callback function.

Here's an example that demonstrates how the useCallback


Hook can be leveraged to optimize further the imaginary
counter component we had in our initial examples:

import { useState, useCallback } from 'react';

const Counter = () => {


const [count, setCount] = useState(0);

const incrementCounter = useCallback(() => {


setCount(count + 1);
}, [count]);

const decrementCounter = useCallback(() => {


setCount(count - 1);
}, [count]);

return (
<div>
Count: {count}
<button onClick={incrementCounter}>Increment</button>
<button onClick={decrementCounter}>Decrement</button>
</div>
);
};

In this example, we define two callback functions,


incrementCounter and decrementCounter , using the

useCallback Hook. We pass [count] as the dependency

https://hygraph.com/blog/react-hooks 13/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

array so that the callbacks will only be recreated if the count


value changes.

This way (memoizing the callbacks with the useCallback


Hook), we ensure that the callbacks are not unnecessarily
recreated on every render, which could lead to unnecessary
re-renders of child components that rely on these callbacks.
Here are some primary use cases for the useCallback Hook:

They optimize performance by preventing unnecessary


re-renders of child components that depend on callback
functions.

They ensure reference equality for callback functions


passed as dependencies to other Hooks or memoized
components.

They help to avoid recreating expensive functions on


every render, especially when passed as props to child
components.

Like useCallback , the useMemo Hook also helps optimize


React applications by caching the results of complex
calculations. Let's discuss it in detail.

The useMemo Hook

The useMemo Hook is another performance optimization


Hook in React. It's designed to memoize the result of a
calculation or an expensive React function to prevent it from
being recomputed on every render of your component. Like
the useCallback Hook, it takes two arguments - a function

https://hygraph.com/blog/react-hooks 14/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

that performs the computation and an array of


dependencies. Here's how it works:

It only recomputes the memoized value when one of its


dependencies changes.

It returns the memoized value, which remains the same


between re-renders unless the dependencies change.

It is primarily used for performance optimization, not as


a semantic guarantee. React can "forget" some
previously memoized values in situations like freeing up
memory for offscreen components, etc.

Here's an improved version of our counter component that


uses the useMemo Hook to enhance its performance.

import { useState, useMemo } from 'react';


function ExpensiveCalculation({ number }) {
// Simulating an expensive calculation
const calculateFactorial = (num) => {
if (num === 0 || num === 1) return 1;
let result = 1;
for (let i = 2; i <= num; i++) {
result *= i;
}
return result;
};
const factorial = useMemo(() => calculateFactorial(number
return <div>Factorial of {number} is {factorial}</div>;
}
function Counter() {
const [count, setCount] = useState(0);
const [number, setNumber] = useState(5);
return (
<div>
<h2>Counter: {count}</h2>
<button onClick={() => setCount(count + 1)}>Increment

<h2>Factorial Calculator</h2>
<input

https://hygraph.com/blog/react-hooks 15/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

type="number"
value={number}
onChange={(e) => setNumber(parseInt(e.target.value)
/>
<ExpensiveCalculation number={number} />
</div>
);
}
export default Counter;

In this example, the result of the ExpensiveCalculation


component was memoized. The real benefit of using
useMemo in this scenario is that the factorial calculation is

only performed when the number changes. As a result,


incrementing the counter doesn't trigger a recalculation of
the factorial.

When used correctly, the useMemo Hook can significantly


improve the speed and responsiveness of your applications.
However, it can also negatively impact your app. Here are
some notable considerations.

In strict mode, React calls the calculation function twice


to help identify accidental impurities.

Overuse or unnecessary memoization can hurt


performance due to difficulty maintaining the cache.
Moving on, let's explore the useContext Hook as an
alternative approach to managing state in React
applications.

The useContext Hook

https://hygraph.com/blog/react-hooks 16/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

Data in React components flow in one direction, from parent


to child, through props. The useContext Hook in React lets
you access data stored in a central location, called a context,
without needing to manually pass props down at every level.
This is useful for managing information that needs to
be available across different parts of your application,
even those not directly connected in the usual parent-
child structure.

The useContext Hook itself doesn't provide mechanisms for


updating the state. It only allows you to read a context's
current value. The actual state updates are typically handled
by the context provider, which often uses useState or
useReducer internally.

Example

import { createContext, useContext } from "react";

const Context = createContext();

const Child = () => {


const context = useContext(Context);
return <div>{context.data}</div>;
};
//Top most component
const App = () => {
return (
<Context.Provider value={{ data: "Data from context!" }
<Child />
</Context.Provider>
);
};

In the snippets above, we created a Context object (i.e., the


central data store) using the createContext() function. This

https://hygraph.com/blog/react-hooks 17/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

object can be accessed from anywhere in your application


and provides two key components: Provider and Consumer
(or the useContext HHook).

The Provider component, positioned higher up in your


component tree, acts as a higher-order component, passing
down its value prop to any nested components that need
access. On the other hand, the Consumer component or the
useContext Hook allows child components to tap into this

shared data.

When the Provider's value changes, any component using


useContext automatically re-renders to reflect the updated

information, ensuring a consistent and synchronized


user interface.

A significant advantage of useContext is that it eliminates


the need for prop drilling, leading to cleaner, more
maintainable code. But be careful not to overuse it, as
frequent updates with a lot of data can slow down your app.

If your context value is complex or changes frequently,


consider using memoization techniques like useMemo to
avoid unnecessary re-rendering of consumer components.
Let's now explore the useRef Hook. Even though it's not
directly tied to context, it often partners with useContext .

The useRef Hook

The useRef Hook provides a way to access and interact with


DOM nodes or store a mutable value that does not cause a
re-render when updated. It creates a "box" that can hold a
https://hygraph.com/blog/react-hooks 18/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

value, which remains unchanged even if the component re-


renders multiple times.

Example

import { useRef } from 'react';

function TextInput() {
const inputRef = useRef(null);

const focusInput = () => {


inputRef.current.focus();
};

return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}

The inputRef object is initialized by calling


useRef(initialValue) . The initialValue can be any

JavaScript value, including null, objects, arrays, or functions.


The ref object has a single property called .current , which
holds the stored value. You can access and modify this value
directly without triggering a re-render of your component.

The useRef Hook provides a way to directly access and


manipulate DOM elements within functional components. It
also stores values that persist across renders, which helps
track input focus, timers, counters, or previous prop values.

When you want changes to be reflected in the UI, you need


to update the ref's .current value manually. Changes to this

https://hygraph.com/blog/react-hooks 19/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

value won't automatically trigger re-renders like changes to


any state managed with useState .

The useRef Hook isn't meant for managing UI state that


triggers re-renders. Still, it's a valuable tool for storing
persistent values or interacting directly with elements in
your webpage.

Now, let's discuss the useId Hook, a simple yet powerful tool
for enhancing accessibility in React applications.

The useId Hook

The Hook used is a utility for generating unique IDs that are
stable across the server and the client renders. This is
particularly important for building accessible web
applications that rely on labels and relationships between
elements, as it ensures consistent IDs for associating
elements like labels and form inputs.

How it works:

The Hook generates a unique ID string when a useId


component is first rendered on the server.

The ID is then sent to the client as part of the HTML, and


React reuses the same ID during hydration, ensuring
consistency between server and client renders.

Each useId call within a component generates a unique


ID. These IDs remain stable across re-renders and
updates unless the component is unmounted and
remounted.

https://hygraph.com/blog/react-hooks 20/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

Example

import { useId } from 'react';

function MyComponent() {
const inputId = useId(); // Generate a unique ID
const labelId = useId();

return (
<div>
<label htmlFor={inputId}>My Input:</label>
<input id={inputId} type="text" />
<p aria-describedby={labelId}>This is a description f
</div>
);
}

In this example, the useId Hook generates unique IDs for the
input and label elements, ensuring a correct association

between them for accessibility purposes.

The useId simplifies creating components by generating


unique IDs, essential for associating labels with React form
inputs and other interactive elements. However, it's limited
to React 18 and later versions and should not be used to
generate keys for dynamic lists. Let’s discuss the
useDeferredValue Hook next.

The useDeferredValue Hook

The useDeferredValue Hook is a performance optimization


tool for deferring updating a value or re-rendering certain
parts of your UI until the browser has time to render
the updates.

https://hygraph.com/blog/react-hooks 21/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

How it works:

It takes two arguments: the value you want to defer (it can
be of any type) and an optional timeout in milliseconds.
React prioritizes rendering other parts of the UI that depend
on the non-deferred value. This means that if the non-
deferred value changes, React will immediately update those
parts, while the parts that rely on the deferred value will
update later in a less urgent manner.

Example

import { useState, useDeferredValue } from 'react';

function MyComponent() {
const [text, setText] = useState('');
const deferredText = useDeferredValue(text);

return (
<div>
<input value={text} onChange={(e) => setText(e.target
<ExpensiveList items={deferredText} />
</div>
);
}

In this example, ExpensiveList depends on deferredText .


When you type something, the input box immediately shows
what you typed. But, the ExpensiveList , which might take
longer to update, waits a moment before it shows the new
text. This keeps the input box snappy and responsive while
the slower part catches up in the background.

By deferring the re-rendering of expensive components, you


can make your UI feel more responsive and avoid UI blocking.
A user can interact with the UI elements (like typing in an

https://hygraph.com/blog/react-hooks 22/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

input field) without experiencing lag, even while heavy


computations or rendering occurs in the background.

The useDeferredValue is particularly effective for optimizing


common UI patterns like:

Search Input with Results List.

Large Lists or Tables.

Complex Calculations.

The useDeferredValue might not be very helpful if the


problem you are trying to solve is not related to slow
rendering. Overusing it can lead to users being served
stale data.

The useDebugValue Hook

The useDebugValue Hook is primarily a developer tool in


React. It's designed to enhance the debugging experience
when working with custom Hooks. It allows you to display a
label for your custom Hook in React DevTools, providing
additional information about its state or value.

Here is how it works:

The useDebugValue is usually called inside your custom


Hook, usually at the top level. It takes two arguments: value
and formatter (optional).

value : The value you want to display in React DevTools.

This can be the current state of your Hook, a calculated

https://hygraph.com/blog/react-hooks 23/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

value, or any relevant information for debugging.

formatter : A function that takes the value and returns

a formatted string. This allows you to customize how the


value is displayed in DevTools.

Example

import { useState, useDebugValue } from 'react';

function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
useDebugValue(count); // Display 'count' in DevTools
// ... (rest of your custom Hook logic)
}

The useDebugValue helps developers gain more insight into


the inner workings of their custom Hooks during
development. It enhances the debugging experience in
React DevTools, making it easier to identify and resolve state
and data flow issues within custom Hooks.

The useDebugValue shines when you use multiple custom


Hooks within a component; it helps you distinguish between
them in DevTools. However, it doesn't change how your
Hooks work, as it's purely a debugging tool. It only applies
during development and doesn't affect the production build
of your application. The following Hook we'll discuss is the
useImperativeHandle Hook.

The useImperativeHandle Hook

https://hygraph.com/blog/react-hooks 24/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

The useImperativeHandle is a React Hook that allows you to


customize the instance value exposed to parent
components when using ref .

To use useImperativeHandle , first, your child component


must be wrapped in the forwardRef function. This allows the
child component to receive a ref object from its parent. In
the child component, call the useImperativeHandle with the
following arguments:

ref : The ref object passed down from the parent.

createHandle : A function that returns an object

containing the methods or values you want to expose to


the parent.

dependencies (optional) : An array of dependencies

that trigger the createHandle function to re-execute if


they change.

Example

import { forwardRef, useRef, useImperativeHandle } from 'react'

const ChildComponent = forwardRef((props, ref) => {


const inputRef = useRef(null);

useImperativeHandle(ref, () => ({
focusInput: () => {
inputRef.current.focus();
},
}));

return <input ref={inputRef} />;


});

function ParentComponent() {
const childRef = useRef(null);

https://hygraph.com/blog/react-hooks 25/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

const handleClick = () => {


childRef.current.focusInput();
};

return (
<div>
<ChildComponent ref={childRef} />
<button onClick={handleClick}>Focus Child Input</butt
</div>
);
}

In this example, the ParentComponent can call focusInput


on the ChildComponent instance through the ref .

Using the useImperativeHandle Hook, you can create


controlled components where the parent can manage the
child's state or behaviour. Instead of exposing the entire
child component instance to the parent, you can expose only
the necessary methods or properties.

The useImperativeHandle Hook shines in creating custom


form inputs with validation logic exposed to the parent
component or controlling video or audio playback from a
parent component.

While useImperativeHandle offers robust control over child


component behavior, it adds complexity that may be
unnecessary for simple interactions, as props and callbacks
typically suffice for most parent-child communication.

The useLayoutEffect Hook

https://hygraph.com/blog/react-hooks 26/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

The useLayoutEffect is a React Hook that is very similar to


useEffect but with a crucial difference in timing. While

useEffect runs after the browser has painted the screen

(i.e., after your component's changes are visually reflected),


useLayoutEffect runs synchronously right before the

browser paints.

How it works:

First, the component renders with the initial state and


props.

React then updates the actual DOM based on the


render.

The useLayoutEffect Hook runs immediately after DOM


changes but before the browser displays them.

The Hook's code executes synchronously, allowing DOM


measurements and manipulations.

The browser then paints the updated UI, reflecting the


changes made by useLayoutEffect .

Example

import { useState, useLayoutEffect } from 'react';

function MyComponent() {
const [dimensions, setDimensions] = useState({ width: 0,
const myRef = useRef(null);

useLayoutEffect(() => {
const element = myRef.current;
if (element) {
setDimensions({
width: element.offsetWidth,
height: element.offsetHeight
});

https://hygraph.com/blog/react-hooks 27/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

}
}, []); // Empty dependency array ensures it runs only on

return (
<div ref={myRef}>
This div's dimensions are: {dimensions.width} x {dime
</div>
);
}

The useLayoutEffect allows you to read the layout from the


DOM and make immediate changes in the next paint. This is
crucial for scenarios like:

Measuring the dimensions of a component after it's


rendered.

Adjusting the position or styling of an element based on


its size or location.

Building canvases and UIs that require complete control


of the layout.

It is best used to calculate dimensions and positions,


perform other layout-related operations, and
synchronize animations with the DOM layout to avoid
visual inconsistencies.

Because the useLayoutEffect Hook runs synchronously, it


can block the browser's rendering pipeline if the effect is
computationally expensive. This can lead to a less
responsive user experience. Let's discuss the
useInsertionEffect Hook next.

The useInsertionEffect Hook


https://hygraph.com/blog/react-hooks 28/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

The useInsertionEffect is a React Hook also introduced in


React 18. It's primarily designed for library authors working
with CSS-in-JS libraries. It allows you to inject styles
or other DOM nodes into the document before layout
calculations occur.

Here's how it works:

The Hook runs immediately after a component is mounted


into the DOM before the browser performs layout
calculations. This ensures that styles are applied before
other effects (like useLayoutEffect or useEffect that might
depend on those styles).

Example

import { useInsertionEffect } from 'react';

useInsertionEffect(() => {
// Code to inject styles or DOM nodes
const styleElement = document.createElement('style');
document.head.appendChild(styleElement);
return () => {
// Cleanup function (optional) to remove the injected n
document.head.removeChild(styleElement);
};
}, [dependencies]); // Optional dependency array

Similar to useLayoutEffect , useInsertionEffect executes


synchronously. As a result, it shouldn't be used for
asynchronous operations. The useInsertionEffect Hook is
designed to optimize the performance of CSS-in-JS libraries.
Injecting styles before the browser calculates layouts
prevents unnecessary and costly recalculations to ensure a
smooth user experience.

https://hygraph.com/blog/react-hooks 29/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

While not typically required for everyday app development,


it's a valuable tool for library authors seeking to enhance
their CSS-in-JS solutions.

The useSyncExternalStore

The useSyncExternalStore Hook is designed for a specific


purpose: subscribing to external data sources and efficiently
synchronizing their updates with your React components.
These external sources can be anything from browser local
storage to a Redux store or even a custom state
management solution.

The useSyncExternalStore subscribes to an external store


and retrieves its current state. It then re-renders your
component whenever the store's state changes, ensuring
your component displays the latest data. The subscription is
cleaned up when the component is removed to prevent
memory leaks.

Here's an example implementation:

import { useSyncExternalStore } from 'react';

function MyComponent() {
const storeState = useSyncExternalStore(
store.subscribe, // Subscribe to the store
store.getSnapshot, // Get the current snapshot
);

return <div>{storeState}</div>;
}

https://hygraph.com/blog/react-hooks 30/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

The useSyncExternalStore provides a way to integrate with


various external stores, abstracting away the complexities of
subscription management. It also works with React's
concurrent features, ensuring smooth rendering and
responsiveness even with complex updates from the
external store.

The useSyncExternalStore shines in synchronizing browser


storage (i.e., keeping your component's state in sync with
localStorage or sessionStorage) and subscribing to external
data streams like WebSockets or server-sent events. Let's
discuss the useTransition Hook next.

The useTransition Hook

The useTransition Hook improves the user experience


when dealing with state updates that could cause your UI to
become unresponsive or slow. It allows you to mark specific
state updates as "transitions," which signals to React
that these updates are less urgent and can be interrupted
if necessary.

How it works

The useTransition returns isPending (boolean) to


show if a transition is happening and startTransition
(function) to mark updates as transitions.

React prioritizes urgent updates over transitions,


ensuring a smooth user experience.

Example

https://hygraph.com/blog/react-hooks 31/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

import { useState, useTransition } from 'react';

function MyComponent() {
const [isPending, startTransition] = useTransition();
const [value, setValue] = useState('');

const handleChange = (event) => {


startTransition(() => {
setValue(event.target.value);
});
};

return (
<div>
<input type="text" value={value} onChange={handleChan
{isPending ? <div>Loading...</div> : <HeavyComponent
</div>
);
}

In this example, updating the value state is marked as a


transition. If the user types quickly into the input , the input
will remain responsive, and the HeavyComponent will only
update after a slight delay, this avoids rendering
substandard UI.

The useTransition makes your app feel smoother and more


responsive, especially during complex updates. It prioritizes
essential changes, like user input, and handles less urgent
updates in the background without you needing to write
extra code.

The useTransition Hook optimizes specific scenarios within


React 18+ applications, such as search inputs, extensive
lists, and complex calculations where immediate UI updates
aren't essential. However, it's important to use it judiciously,

https://hygraph.com/blog/react-hooks 32/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

as it's not suitable for urgent updates and can introduce


unnecessary complexity if overused.

Beyond the established Hooks, React boasts a set of


experimental Hooks, offering a glimpse into the framework's
future. These Hooks are still in development and might
change, so they're not recommended for production use yet.
However, they provide key features, like optimistic UI
updates (showing changes before they're confirmed) and
handling actions with built-in state management
( useOptimistic and useActionState , respectively).

The useOptimistic Hook

The useOptimistic is designed to enhance the perceived


responsiveness of your UI by allowing you to optimistically
update the UI before an asynchronous action (like a network
request) is complete. This means the user sees the
expected outcome immediately, even though the action is
still in progress. React will revert the UI to its previous state if
the action fails.

How it works:

The useOptimistic takes an action function and an


initial optimistic value.

It returns the current value, a pending status indicator,


and a reset function.

The current value starts as optimistic, changes during


the action, and updates with the actual result.

https://hygraph.com/blog/react-hooks 33/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

Example

import { useState, useOptimistic } from 'react';

function MyComponent() {
const [comments, setComments] = useState([]);

const [newComment, addNewComment] = useOptimistic(


(text) => fetch('/api/comments', { method: 'POST', body
'' // Initial optimistic value is an empty string
);

const handleSubmit = async (event) => {


event.preventDefault();
await addNewComment(newComment); // Trigger the action
setComments([...comments, newComment]); // Update comme
setNewComment(''); // Clear the input field
};

// ...
}

The useActionState Hook

The useActionState is often used in conjunction with


useOptimistic . It simplifies the management of the state

associated with an asynchronous action. It automatically


tracks the action's status (pending, success, error) and
provides convenient methods for handling its result.

How it works:

First, you must provide an action function to


useActionState to handle the asynchronous operation.

The useActionState returns the action's current state


( idle , pending , success , or error ), a function to
https://hygraph.com/blog/react-hooks 34/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

trigger the action ( dispatch ), and a function to reset


the state ( reset ).

The returned state object contains the action's status,


returned value, and potential errors.

Example

import { useActionState } from 'react';

function MyComponent() {
const [commentState, addComment] = useActionState(
(text) => fetch('/api/comments', { method: 'POST', body
);

// ...
}

The useOptimistic and useActionState Hooks work


together to enhance user interactions. Optimistically,
updating the UI before an action is complete gives the user a
more responsive experience.

Additionally, useActionState simplifies the handling of state


associated with asynchronous actions, such as network
requests. It automatically tracks the action's status
(pending, success, error), reducing the need for manual
state updates and providing built-in error management.

It's important to know that these experimental Hooks are still


under development, may introduce complexity, and their
behavior could change in future React versions, so use them
with caution.

https://hygraph.com/blog/react-hooks 35/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

Conclusion

React Hooks have revolutionized functional component


development, offering a straightforward way to manage
state, side effects, and other crucial aspects. From basic
state updates with useState to optimizing performance
with useMemo and useCallback , these Hooks empower
developers to build more efficient, maintainable, and
interactive applications. While experimental Hooks like
useOptimistic and useActionState are still evolving,

they hint at an even brighter future for React


development, promising enhanced user experiences and
streamlined workflows.

Ready to explore React Hooks' full potential? Sign up for your


free developer account and join the Hygraph developer
community, where you'll find extensive resources, tutorials,
and discussions to help you master these powerful tools.
Stay curious, experiment with new Hooks, and unlock the full
potential of React in your projects.

BLOG AUTHOR
Chidi Eze
Technical writer
Chidi is a software engineer and technical
writer with experience in building user-friendly
applications and creating content around
composable architectures.

Share with others


https://hygraph.com/blog/react-hooks 36/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

Sign up for our newsletter!

Be the first to know about releases


and industry news and insights.

Your email

Submit

Explore more blogs


from Hygraph

Frontend APIs Frontend

How to …
React React
GraphQL
useRef( useCallb
- A… - A…
React
Learn how Prevent
useEffec
to use unnecessa
React's…
- A… re-…
Master
React
useEffec…

https://hygraph.com/blog/react-hooks 37/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

Dec 09, Aug 26, Nov 07,

2024 2024 2024

COMPANY KEY CONCEPTS


About Us Headless CMS

Contact Sales Content Federation

Careers Composable Architectures

Support Frameworks

Talk to our AI agent Headless CMS Comparison

FAQ GraphQL Playground

Terms

Privacy

Imprint

Sitemap

PRODUCT RESOURCES
Features What Is A Headless CMS?

Marketplace What Is GraphQL?

Hygraph For Engineering Teams GraphQL Cheatsheet

Hygraph For Content Creators Customer Case Studies

Hygraph For Businesses Academy

For Enterprise Documentation

Partners Resource Hub

Pricing Events

Changelog Blog

https://hygraph.com/blog/react-hooks 38/39
14/01/2025, 17:28 React Hooks: The only guide you’ll ever need | Hygraph

Feature Requests Solutions

API Status Write for Hygraph

© 2025 - All Rights Reserved.

https://hygraph.com/blog/react-hooks 39/39

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy