Home » Advanced React Hooks

Advanced React Hooks

Introduction to Advanced React Hooks

React Hooks changed how we write React applications.

Before hooks, developers relied heavily on class components to manage state and lifecycle methods. But with the introduction of hooks in React 16.8, everything became simpler, cleaner, and more reusable.

What are React Hooks?

React Hooks are special functions that let you use state and lifecycle features inside functional components.

What are Advanced React Hooks?

Advanced React Hooks are powerful built-in and custom hooks like useReducer, useContext, useMemo, and useCallback that help manage complex state, optimize performance, and improve code reusability in modern React applications.

These hooks are essential when:

  • Your app grows in complexity
  • You need better performance
  • You want clean and reusable logic

Why Advanced Hooks Matter

Think of basic hooks like useState as a small toolbox.

Advanced hooks?
They are your full professional toolkit.

They help you:

  • Manage complex state logic
  • Avoid unnecessary re-renders
  • Share logic across components
  • Build scalable applications

useReducer Hook

What is useReducer?

useReducer is a React hook used for managing complex state logic using a reducer function instead of multiple useState calls.

When to Use

  • Global state (theme, user login)
  • Avoid prop drilling
  • App-wide settings

Analogy

Think of useContext like Wi-Fi:

  • Once connected, everyone can access it
  • No need to pass cables (props)

Code Example

import React, { createContext, useContext } from "react";

const ThemeContext = createContext("light");

function Child() {
  const theme = useContext(ThemeContext);
  return <p>Theme: {theme}</p>;
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Child />
    </ThemeContext.Provider>
  );
}

useContext

What is useContext?

useContext allows you to access shared data across components without passing props manually at every level.

import React, { createContext, useContext, useState } from 'react';

const UserContext = createContext();

function ParentComponent() {
  const [user, setUser] = useState({ name: 'John' });

  return (
    <UserContext.Provider value={user}>
      <ChildComponent />
    </UserContext.Provider>
  );
}

function ChildComponent() {
  const user = useContext(UserContext);
  return <p>Welcome, {user.name}!</p>;
}

export default ParentComponent;

useMemo: Optimizing Expensive Calculations

The useMemo hook memoizes a computed value to avoid recalculations when dependencies haven’t changed.

Syntax

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

Example

import React, { useState, useMemo } from 'react';

function ExpensiveCalculation({ num }) {
  const compute = (n) => {
    console.log('Computing...');
    return n * 2;
  };

  const memoizedValue = useMemo(() => compute(num), [num]);

  return <p>Computed Value: {memoizedValue}</p>;
}

useRef Hook

What is useRef?

useRef is used to store mutable values that do not trigger re-renders when updated.

 When to Use

  • Access DOM elements
  • Store previous values
  • Persist data without re-render

 Analogy

Think of useRef like a box:

  • You can put anything inside
  • Changing it won’t refresh UI

Code Example

import React, { useRef } from "react";

function InputFocus() {
  const inputRef = useRef();

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <>
      <input ref={inputRef} />
      <button onClick={focusInput}>Focus</button>
    </>
  );
}

useMemo Hook

What is useMemo?

useMemo is used to memoize expensive calculations so they are not recomputed on every render.

When to Use

  • Heavy computations
  • Filtering large lists
  • Performance optimization

Analogy

Like saving your work in cache instead of recalculating every time.

Code Example

import React, { useMemo, useState } from "react";

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

  const expensiveCalculation = useMemo(() => {
    console.log("Calculating...");
    return count * 2;
  }, [count]);

  return (
    <div>
      <p>{expensiveCalculation}</p>
      <button onClick={() => setCount(count + 1)}>Increase</button>
    </div>
  );
}

useCallback Hook

What is useCallback?

useCallback returns a memoized function so it doesn’t get recreated on every render.

When to Use

  • Passing functions to child components
  • Prevent unnecessary re-renders

Analogy

Think of it like saving a function instead of recreating it again and again.

Code Example

import React, { useCallback, useState } from "react";

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

  const handleClick = useCallback(() => {
    console.log("Clicked");
  }, []);

  return <Child onClick={handleClick} />;
}

function Child({ onClick }) {
  return <button onClick={onClick}>Click Me</button>;
}

useLayoutEffect Hook

What is useLayoutEffect?

useLayoutEffect runs synchronously after DOM updates but before the browser paints.

 When to Use

  • Measuring DOM elements
  • Avoiding UI flicker
  • Layout calculations

Code Example

import React, { useLayoutEffect, useRef } from "react";

function LayoutExample() {
  const boxRef = useRef();

  useLayoutEffect(() => {
    console.log(boxRef.current.getBoundingClientRect());
  }, []);

  return <div ref={boxRef}>Box</div>;
}

Custom Hooks

What are Custom Hooks?

Custom Hooks are reusable functions that encapsulate logic using other React hooks.

 Analogy

Like creating your own mini tool from existing tools.

Example

import { useState } from "react";

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

  const increment = () => setCount(c => c + 1);

  return { count, increment };
}

Real-World Example (Combining Hooks)

import React, { useState, useMemo, useCallback } from "react";

function SearchApp() {
  const [query, setQuery] = useState("");

  const data = ["React", "Angular", "Vue"];

  const filtered = useMemo(() => {
    return data.filter(item => item.toLowerCase().includes(query));
  }, [query]);

  const handleChange = useCallback((e) => {
    setQuery(e.target.value);
  }, []);

  return (
    <div>
      <input onChange={handleChange} />
      {filtered.map(item => <p key={item}>{item}</p>)}
    </div>
  );
}

Performance Optimization Tips

Memoization

  • Use useMemo for values
  • Use useCallback for functions

Avoid Re-Renders

  • Use React.memo
  • Stable references

Efficient State Management

  • Prefer useReducer for complex logic

Common Mistakes

  • Overusing useMemo / useCallback
  • Missing dependency arrays
  • Misusing useContext for frequent updates
  • Not extracting custom hooks

Best Practices for Advanced Hooks

  • Keep Dependencies Accurate: Always include dependencies for useMemo and useCallback.
  • Avoid Overuse: Use hooks like useMemo and useCallback only when performance issues arise.
  • Abstract Logic: Use Custom Hooks for cleaner, reusable code.
  • Combine Hooks Thoughtfully: Leverage multiple hooks for complex scenarios.

FAQs

1. What are Advanced React Hooks?

Advanced React Hooks are hooks like useReducer, useMemo, and useCallback used for complex state and performance optimization.

2. When should I use useReducer instead of useState?

Use it when state logic becomes complex or involves multiple related values.

3. Is useMemo always needed?

No, only for expensive computations.

4. Difference between useMemo and useCallback?

  • useMemo → returns value
  • useCallback → returns function

5. Are custom hooks necessary?

Yes, for reusable logic and cleaner code.

Scroll to Top