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>;
}
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();
}, []);
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} />;
Real-world: Managing focus, storing timers, accessing DOM.
- 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);
Real-world: Theme switching, user authentication data.
- 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 });
Real-world: Forms, state machines, undo/redo.
- 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]);
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]);
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} />;
});
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;
});
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");
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();
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);
Real-world: Debouncing, notifications.
- 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);
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);
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');
useTransition (React 18+)
When: Prioritize urgent UI updates.
Why: Prevent jank during heavy renders.
How:
const [isPending, startTransition] = useTransition();
startTransition(() => { /* Non-urgent update */ });
useDeferredValue (React 18+)
When: Defer non-urgent updates.
Why: Keep UI responsive.
How:
const deferredQuery = useDeferredValue(query);
Example: Delayed search results rendering.
- useId (React 18+) When: Generate unique IDs for accessibility. Why: Avoid SSR/client mismatches. How:
const id = useId();
return <label htmlFor={id}>Username</label>;
Example: Accessible form labels.
useDispatch (React-Redux)
When: Trigger Redux store actions.
Why: Centralized state management.
How:
const dispatch = useDispatch();
dispatch({ type: 'ADD_ITEM' });
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);
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)