Debug School

rakesh kumar
rakesh kumar

Posted on

Application of hooks in react

Why We Use Hooks in React
Different kind of hooks
Question on React hooks

We use hooks in React to enable functional components to use features that were previously only available in class components, such as state management and lifecycle methods. Here’s why hooks are important:

Why We Use Hooks in React

State and Lifecycle in Functional Components:
Hooks like useState and useEffect allow functional components to manage state and side effects, making class components largely unnecessary.

Simplified and Cleaner Code:
Hooks eliminate the boilerplate and complexity of classes, making components easier to write, read, and maintain.

Logic Reusability:
With hooks, you can extract and reuse logic across components by creating custom hooks, promoting modularity and reducing code duplication.

Better Code Organization:
Hooks let you group related logic together (such as state and effects) within a single function, improving code readability and maintainability.

Enhanced Performance and Smaller Bundles:
Functional components with hooks are generally lighter and can result in smaller bundle sizes compared to class components.

Easier Testing and Debugging:
Hooks encourage separation of concerns and functional programming patterns, making components more predictable and easier to test

Different kind of hooks

useState
Purpose: Manage local component state.
Example: Counter button.
When: Track dynamic component state (e.g., form inputs, UI toggles).
Why: Replace class component this.state with functional state.

import { useState } from "react";
function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>;
}
Enter fullscreen mode Exit fullscreen mode

Real-world: Toggle modals, track input values.

useEffect
Purpose: Handle side effects (data fetching, subscriptions).
Example: Fetch data on mount.
When: Handle side effects (API calls, subscriptions).
Why: Manage lifecycle events in functional components.

import { useEffect } from "react";
useEffect(() => {
  fetchData();
}, []);
Enter fullscreen mode Exit fullscreen mode

Real-world: API calls, event listeners, updating document title.

useRef
Purpose: Reference DOM elements or persist mutable values.
Example: Focus input on mount.
When: Access DOM elements or persist values between renders.
Why: Avoid re-renders for non-state data.

import { useRef, useEffect } from "react";
const inputRef = useRef(null);
useEffect(() => { inputRef.current.focus(); }, []);
return <input ref={inputRef} />;
Enter fullscreen mode Exit fullscreen mode

Real-world: Managing focus, storing timers, accessing DOM.

  1. useContext Purpose: Access global data without prop drilling. Example: Theme context. When: Access global data (e.g., themes, user auth). Why: Avoid prop drilling.
import { useContext } from "react";
const theme = useContext(ThemeContext);
Enter fullscreen mode Exit fullscreen mode

Real-world: Theme switching, user authentication data.

  1. useReducer Purpose: Manage complex state logic. Example: Counter with reducer.

When: Manage complex state logic (e.g., forms, multi-step workflows).
Why: Centralize state updates via actions.

import { useReducer } from "react";
function reducer(state, action) {
  switch (action.type) {
    case "increment": return { count: state.count + 1 };
    default: return state;
  }
}
const [state, dispatch] = useReducer(reducer, { count: 0 });
Enter fullscreen mode Exit fullscreen mode

Real-world: Forms, state machines, undo/redo.

  1. useMemo Purpose: Memoize expensive calculations. Example: Expensive computation. When: Cache expensive calculations. Why: Optimize performance.
import { useMemo } from "react";
const result = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Enter fullscreen mode Exit fullscreen mode

Real-world: Filtering large lists, optimizing performance.

useCallback
Purpose: Memoize functions to prevent unnecessary re-renders.
Example: Memoized click handler.
When: Prevent unnecessary re-renders of child components.
Why: Memoize function references.

import { useCallback } from "react";
const handleClick = useCallback(() => { doSomething(); }, [dependency]);
Enter fullscreen mode Exit fullscreen mode

Real-world: Passing stable callbacks to child components.

useImperativeHandle
Purpose: Customize instance value exposed to parent via ref.
Example: Expose custom methods.

When: Expose child component methods to parents.
Why: Customize ref behavior.

import { useImperativeHandle, forwardRef, useRef } from "react";
const MyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => inputRef.current.focus()
  }));
  return <input ref={inputRef} />;
});
Enter fullscreen mode Exit fullscreen mode

Real-world: Custom input controls, modal controls.

useLayoutEffect
Purpose: Like useEffect, but fires synchronously after DOM mutations.
Example: Measure DOM nodes.

When: Measure DOM elements before paint.
Why: Synchronous layout calculations.

import { useLayoutEffect, useRef } from "react";
const boxRef = useRef();
useLayoutEffect(() => {
  const width = boxRef.current.offsetWidth;
});
Enter fullscreen mode Exit fullscreen mode

Real-world: Animations, measuring elements before paint.

useDebugValue
Purpose: Display debug information in React DevTools.
Example:
When: Debug custom hooks in DevTools.
Why: Label custom hook values.

import { useDebugValue } from "react";
useDebugValue(value ? "Online" : "Offline");
Enter fullscreen mode Exit fullscreen mode

Real-world: Custom hooks debugging.

useToggle (Custom Hook)
Purpose: Toggle boolean state.
Example:

function useToggle(initial = false) {
  const [value, setValue] = useState(initial);
  const toggle = () => setValue(v => !v);
  return [value, toggle];
}
// Usage:
const [open, toggleOpen] = useToggle();
Enter fullscreen mode Exit fullscreen mode

Real-world: Show/hide UI elements.

useTimeout (Custom Hook)
Purpose: Set and clear timeouts easily.
Example:

function useTimeout(callback, delay) {
  const timeoutRef = useRef();
  useEffect(() => {
    timeoutRef.current = setTimeout(callback, delay);
    return () => clearTimeout(timeoutRef.current);
  }, [callback, delay]);
}
// Usage:
useTimeout(() => setCount(0), 1000);
Enter fullscreen mode Exit fullscreen mode

Real-world: Debouncing, notifications.

  1. useDebounce (Custom Hook) Purpose: Debounce value or callback.
function useDebounce(value, delay) {
  const [debounced, setDebounced] = useState(value);
  useEffect(() => {
    const handler = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(handler);
  }, [value, delay]);
  return debounced;
}
// Usage:
const debouncedSearch = useDebounce(searchTerm, 500);
Enter fullscreen mode Exit fullscreen mode

Real-world: Search input, API requests.

usePrevious (Custom Hook)
Purpose: Track previous value.
Example:

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => { ref.current = value; });
  return ref.current;
}
// Usage:
const prevCount = usePrevious(count);
Enter fullscreen mode Exit fullscreen mode

Real-world: Compare previous and current state.

useFetch (Custom Hook)
Purpose: Simplify data fetching logic.
Example:

function useFetch(url) {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(setData);
  }, [url]);
  return data;
}
// Usage:
const user = useFetch('/api/user');
Enter fullscreen mode Exit fullscreen mode

useTransition (React 18+)
When: Prioritize urgent UI updates.
Why: Prevent jank during heavy renders.
How:

const [isPending, startTransition] = useTransition();
Enter fullscreen mode Exit fullscreen mode

startTransition(() => { /* Non-urgent update */ });

useDeferredValue (React 18+)
When: Defer non-urgent updates.
Why: Keep UI responsive.
How:

const deferredQuery = useDeferredValue(query);
Enter fullscreen mode Exit fullscreen mode

Example: Delayed search results rendering.

  1. useId (React 18+) When: Generate unique IDs for accessibility. Why: Avoid SSR/client mismatches. How:
const id = useId();
return <label htmlFor={id}>Username</label>;
Enter fullscreen mode Exit fullscreen mode

Example: Accessible form labels.

useDispatch (React-Redux)
When: Trigger Redux store actions.
Why: Centralized state management.
How:

const dispatch = useDispatch();
dispatch({ type: 'ADD_ITEM' });
Enter fullscreen mode Exit fullscreen mode

Example: Add items to a cart.

useSelector (React-Redux)
When: Access Redux store state.
Why: Avoid prop drilling in Redux apps.
How:

const cartItems = useSelector(state => state.cart.items);
Enter fullscreen mode Exit fullscreen mode

Question on React hooks

What are React Hooks, and why were they introduced?

What is the difference between class components and functional components with hooks?

What are the rules of using hooks in React?

What is the difference between state and props in React?

What are the basic built-in hooks in React, and what do they do?

How does the useState hook work?

When should you use useReducer instead of useState?

How does the useEffect hook differ from useLayoutEffect?

What is the purpose of the useContext hook?

How do you memoize values or functions in React, and what is the difference between useMemo and useCallback?

What is the useRef hook used for, and how does it differ from state?

How do you create and use custom hooks in React?

What is the difference between calling a hook at the top level and inside a loop, condition, or nested function?

What is the useImperativeHandle hook, and when would you use it?

How do you debug custom hooks, and what is the use of useDebugValue?

How do you share state or logic between multiple components using hooks?

What is the difference between useEffect and useMemo?

How do you manage side effects in React functional components?

What are the advantages and disadvantages of using hooks over class lifecycle methods?

How do you test components and custom hooks that use React hooks?

Top comments (0)