Loading...

What are Custom Hooks in React?

9 Mins
Pravin Prajapati  ·   29 Jan 2025
custom hooks in react
service-banner

useState, useContext, and useEffect. These words are the routine lyrics in your mind if you work as a React JS developer. Create a custom hook, or you must be aware of importing hooks from React.

Hooks make your development process quick by using components in different ways in your code. It helps in saving you and making your code more simple and organized. Utilizing hooks can significantly enhance the functionality of your React applications.

With this proper document, we explain what a hook is in React. The core hook is provided by React, and how to use React hooks correctly in your code. Using this hook makes your project faster and less maintainable.

What is a Hook in React?

A Hook is a special function in React that allows you to "hook into" built-in React features, such as state management or lifecycle events, without needing to write a class component.

Hooks lets you use state and other React features without writing a class. It stands out from the other tools you can get because you can make your own. You can abstract and reuse stateful logic across components, making managing your logic and code DRY (Don't Repeat Yourself) more straightforward.

For example, useState is a Hook that lets you add and manage a state in a function component.

Why Use a React Hook?

Before Hooks, if you needed to use state in a component, you had to write it as a class component. With Hooks, you can keep your components as simple functions and still use state or other React features. This makes your code cleaner and easier to understand.

Hooks allow you to reuse logic across different components, making your code more modular and easier to maintain. You can create complex logic easier to reuse and read by using custom hooks to contain and share it between multiple components.

A Quick Example
import React, { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0); // useState is a Hook

  return (
    

You clicked {count} times

); }

How It Works:

  • useState(0): This initializes a state variable (count) with a starting value 0.
  • setCount: This function is used to update the state (count).

Every time setCount is called, React re-renders the component to reflect the new state.

When to Use React Hooks?

  • When you're writing a function component and need features like state, side effects, or context.
  • They let you reuse logic between components in a cleaner, more modular way.

Hooks make React more powerful and flexible without the complexity of class components!

15 Core Hooks in React Js Library!

React provides several core hooks that allow developers to manage states, handle side effects, work with contexts, refs, and more. Here's a comprehensive list of these core hooks, along with a brief explanation of each:

1. useState

Manages state in functional components

const [state, setState] = useState(initialValue);
  • Used to add local state to a component.
  • Returns the current state value and a function to update it.

2. useEffect

Handles side effects in functional components

useEffect(() => { /* Side effect logic */ }, [dependencies]);
  • Runs after render to handle operations like data fetching, subscriptions, or DOM updates.
  • Dependencies control when the effect runs.

3. useContext

Accesses values from a React context

const value = useContext(MyContext);
  • Simplifies consuming values provided by a context without needing a Consumer component.

4. useReducer

An alternative to useState for complex state logic

const [state, dispatch] = useReducer(reducer, initialState);
  • Similar to Redux reducers but built into React.
  • Suitable for managing state transitions with actions.

5. useRef

Creates a mutable object that persists across renders

const ref = useRef(initialValue);
  • Commonly used for DOM manipulation or storing mutable values without triggering re-renders.

6. useMemo

Memoizes expensive calculations to improve performance

const memoizedValue = useMemo(() => computeExpensiveValue(), [dependencies]);
  • Ensures a value is recalculated only when its dependencies change.

7. useCallback

Memoizes functions to avoid unnecessary re-creations

const memoizedCallback = useCallback(() => { /* Function logic */ }, [dependencies]);
  • Useful when passing functions as props to child components.

8. useLayoutEffect

Runs synchronously after all DOM mutations

useLayoutEffect(() => { /* Synchronous side effects */ }, [dependencies]);
  • Similar to useEffect but runs before the browser paints.

9. useImperativeHandle

Customizes the ref exposed by a component

useImperativeHandle(ref, () => ({ customMethod() { /* Custom logic */ } }));
  • Used with React.forwardRef to control what the parent component can access.

10. useDebugValue

Custom labels for debugging hooks in React DevTools

useDebugValue(value, formatterFunction);
  • Primarily used in custom hooks to provide insight into their state.

11. useId

Generates a unique ID for accessibility or identification purposes

const id = useId();
  • Useful for associating labels with form elements.

12. useDeferredValue

Defers the update of a value for better UI performance

const deferredValue = useDeferredValue(value);
  • Helpful in making non-urgent updates while keeping the UI responsive.

13. useTransition

Manages state transitions to prioritize rendering

const [isPending, startTransition] = useTransition();
  • Allows marking updates as low-priority to improve performance during heavy renders.

14. useSyncExternalStore

Subscribes to an external store

const state = useSyncExternalStore(subscribe, getSnapshot);
  • Ensures consistent state with external systems (e.g., Redux or other state management libraries).

15. useInsertionEffect

Injects styles into the DOM before rendering

useInsertionEffect(() => { /* Inject styles */ }, [dependencies]);
  • Useful for CSS-in-JS libraries or managing critical styles.

Developers can handle complex logic, manage performance, and make highly reusable, modular parts by combining these hooks.

The Building Blocks of Custom Hooks

Before we jump into creating custom hooks, it’s important to understand the foundational hooks provided by React. These are the "building blocks" that enable custom hooks to exist. Let’s recap two essential hooks: useState and useEffect.

1. useState

The useState hook is used to add and manage state in functional components. With useState, you can make your components dynamic and interactive.

Basic Example:
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // Declares a state variable `count`

  return (
    

You clicked {count} times

); }
What's Happening Here?
  • State Initialization: useState(0) initializes the state variable count with a value of 0.
  • State Setter Function: setCount is used to update the count variable.
  • Re-rendering: Every time setCount is called, React re-renders the component with the updated state.

2. useEffect

The useEffect hook lets you perform side effects in functional components. A side effect can include tasks like:

  • Fetching data from an API
  • Subscribing to events
  • Manually updating the DOM
Basic Example:
import { useState, useEffect } from 'react';

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

  // Effect hook for performing side effects
  useEffect(() => {
    // Update the document title whenever `count` changes
    document.title = `You clicked ${count} times`;
  });

  return (
    

You clicked {count} times

); }
What's Happening Here?
  • Side Effect Execution: The code inside useEffect runs after the component renders. In this case, it updates the browser's title whenever the count changes.
  • Dependency Tracking: By default, useEffect runs on every render, but you can optimize it to run only when certain variables (like count) change by adding a dependency array.

Why are These Hooks Important for Custom Hooks?

Custom hooks are essentially functions that combine React's basic hooks like useState and useEffect to encapsulate reusable logic. By mastering useState and useEffect, you gain the tools to:

  • Manage local state (useState) within a custom hook.
  • Handle side effects (useEffect) for tasks like fetching data or subscriptions.

How to Build Custom React Hooks?

Before we jump into creating custom hooks, it’s important to understand the foundational hooks provided by React. These are the "building blocks" that enable custom hooks to exist. Let’s recap two essential hooks: useState and useEffect.

1. useState

The useState hook is used to add and manage state in functional components. With useState, you can make your components dynamic and interactive.

Basic Example:
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // Declares a state variable `count`

  return (
    

You clicked {count} times

); }
What's Happening Here?
  • State Initialization: useState(0) initializes the state variable count with a value of 0.
  • State Setter Function: setCount is used to update the count variable.
  • Re-rendering: Every time setCount is called, React re-renders the component with the updated state.

2. useEffect

The useEffect hook lets you perform side effects in functional components. A side effect can include tasks like:

  • Fetching data from an API
  • Subscribing to events
  • Manually updating the DOM
Basic Example:
import { useState, useEffect } from 'react';

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

  // Effect hook for performing side effects
  useEffect(() => {
    // Update the document title whenever `count` changes
    document.title = `You clicked ${count} times`;
  });

  return (
    

You clicked {count} times

); }
What's Happening Here?
  • Side Effect Execution: The code inside useEffect runs after the component renders. In this case, it updates the browser's title whenever the count changes.
  • Dependency Tracking: By default, useEffect runs on every render, but you can optimize it to run only when certain variables (like count) change by adding a dependency array.

Why are These Hooks Important for Creating Custom Hooks?

Custom hooks are functions that combine React's core hooks like useState and useEffect to encapsulate reusable logic. By mastering useState and useEffect, you gain the tools to:

  • Manage local state (useState) within a custom hook.
  • Handle side effects (useEffect) for tasks like fetching data or subscriptions.

How to Build Custom React Hooks?

The example of custom hook might look something like this:

import { useState, useEffect } from 'react';

function useDocumentTitle(title) {
  useEffect(() => {
    document.title = title; // Side effect
  }, [title]); // Re-run only when `title` changes
}

// Example usage:
function App() {
  const [title, setTitle] = useState('Hello, World!');

  useDocumentTitle(title); // Reusable logic in a custom hook

  return (
    
setTitle(e.target.value)} placeholder="Change document title" />
); }

useState and useEffect are the core building blocks of custom hooks. They allow you to create modular, reusable, and clean logic that can be shared across components, enhancing the flexibility and scalability of your React code.

How Custom Hooks Help Reuse Logic Across Components?

Custom hooks in React allow developers to extract and reuse logic that can be shared across multiple components. Doing this can help reduce duplicate code and make the app easier to maintain and expand.

  • Encapsulation and Simplicity: Custom hooks wrap specific logic into reusable functions. They hide the complex details and offer a simple way to interact with that logic, making it easy to use the same functionality across multiple components.
  • Modularity: Custom hooks organize your code by breaking application logic into smaller, reusable units. You can reuse hooks to handle tasks like fetching data, managing state, handling side effects, and simplifying component building.
  • Code Reusability: Once a custom hook is created, it can be reused in different components within the same app or even in other projects. This avoids repeating the same logic, saving time and effort.
  • Consistency and Easier Updates: Using the same custom hook in multiple components ensures consistent behavior. If you update or improve the hook, all the components using it automatically benefit from the changes, reducing the chance of errors.
  • Cleaner Code with Separation of Concerns: Custom hooks help separate logic from component code. This keeps your components focused on their primary purpose while the hooks handle the complex logic, resulting in cleaner, easier-to-read code.

Custom hooks in React make it easier to reuse logic, organize your code, maintain consistency, and keep your components clean and efficient, leading to scalable and maintainable applications.

Rules of using Hooks in React

If you want to perform your hooks smoothly, follow the mentioned things when you add hooks to your code. It helps your hook trigger quickly:

  • Call Hooks at the Top Level
    1. Always call Hooks at the very top of your React function.
    2. Avoid placing them inside loops, conditions, nested functions, or after conditional returns.
    3. This ensures hooks are called in the same order during every render, which is essential for React to track the state properly.
  • Don't Use Hooks in Event Handlers or Class Components
    1. Hooks are designed for functional components or custom hooks.
    2. Using them in class components or event handlers can cause unexpected behavior.
  • Use Hooks Only in React Functions or Custom Hooks
    1. Hooks should only be used in React functional components or within custom hooks.
    2. For example, custom hooks like useForm can call other hooks like useValidation but still follow the same rules.

When you use custom hooks to hide shared logic, your code will be cleaner, easier to test, and more scalable for future needs.

Can Hooks Be Used for All Types of Classes?

Right now, Hooks aim to cover most of the ways classes can be used in React. However, there are a few lifecycle methods that don't yet have direct Hook equivalents, such as:

  • getSnapshotBeforeUpdate
  • getDerivedStateFromError
  • componentDidCatch

These methods are less commonly used but necessary for specific scenarios, such as error handling and capturing snapshots before DOM updates. React plans to add equivalent features for these lifecycles to ensure Hooks can fully replace classes in all use cases.

For now, if your application relies on these specific lifecycle methods, you may still need to use class components. Otherwise, Hooks are a reliable and modern alternative for managing the state and lifecycle of functional components.

Essence

React hooks revolutionize how developers manage state and lifecycle events, allowing for cleaner, reusable, and modular code. You can build scalable, maintainable applications that simplify logic sharing across components by mastering core hooks and creating custom hooks. Whether you're a beginner or an experienced developer, leveraging hooks effectively is a key skill for modern React development.

We hope this guide will help you in the right direction if you seek the right solution. The future and demand for ReactJS development are growing daily in application development. The experienced developers from Elightwalk Technology help to build React applications with best practices in mind, ensuring efficiency and performance. You can stay ahead of the curve and make great React apps to meet the growing demand in the industry with their help.

FAQs about React Hooks

What is a Hook in React?

Why should I use Hooks?

When should I use custom hooks?

Can I use hooks in class components?

Are there any lifecycle methods that don't have hook equivalents?

Pravin Prajapati
Full Stack Developer

Expert in frontend and backend development, combining creativity with sharp technical knowledge. Passionate about keeping up with industry trends, he implements cutting-edge technologies, showcasing strong problem-solving skills and attention to detail in crafting innovative solutions.

Most Visited Blog

Easy Ways to Check If an Array is Empty in JavaScript
In this quick guide for checking an empty array in JavaScript, we streamline the code and create an easy way to check an empty array in simple steps. Carefully read this guide. This will help you efficiently address empty arrays in your JavaScript code.
The Best Optimization Techniques in React
Gain valuable insights to improve your app's performance, backed by expert advice from our seasoned ReactJS developers. Discover how top companies like CSDN, Dropbox, and LinkedIn recommend optimising your ReactJS code. Contact us if you need expert help to grow your app.
What is ReactJs Development?
This comprehensive guide walks you through various facets of React JS development, including its library versus framework debate, harnessing Hooks for state management, leveraging the Context API, mastering form creation and event handling, and embracing the latest trends in React JS development.