Top 30 Frequently Asked React Hooks Interview Questions (2026)
Discover the top 30 most-asked React Hooks Interview Questions, with detailed explanations and code examples for quick revision.
Anuj Sharma
Last Updated Jun 26, 2026

In the modern frontend landscape, React hooks have become the standard for managing state, side effects, and component lifecycles. Mastering them is no longer optional; it is a prerequisite for any developer aiming to pass a technical interview.
Here are the Top 30 Frequently Asked React Hooks Interview Questions, ranging from foundational concepts to advanced performance patterns.
Foundations of Hooks
Q1. What are React Hooks and why were Hooks introduced in React?
React Hooks are functions that allow you to use state and other React features in functional components. They were introduced to provide a more direct API to React concepts without the need for class components.
Q2. What are the benefits of using Hooks?
Hooks in React provide a way to use state and lifecycle features in functional components. Here are some benefits of using Hooks:
Benefits of using Hooks:
- Simplifies Component Logic: Hooks allow you to reuse stateful logic without changing your component hierarchy.
- Improved Code Readability: With Hooks, related logic can be grouped together in a more cohesive manner, enhancing code readability.
- Encourages Reusability: Custom Hooks can encapsulate logic for reuse across multiple components, promoting code reusability.
- Reduces Boilerplate Code: Hooks eliminate the need for class components and related boilerplate code, resulting in cleaner and concise code.
- Better Performance Optimization: Hooks provide optimization opportunities with features like
useMemoanduseCallbackto avoid unnecessary re-renders. - Easier to Understand Lifecycle: Hooks offer a more straightforward way to manage component lifecycle with
useEffectanduseLayoutEffect.
Q3. What are the "Rules of Hooks"?
In React, the "Rules of Hooks" are guidelines that must be followed when using Hooks in functional components. They ensure the correct usage and behavior of Hooks.
- Only Call Hooks at the Top Level:
Do not call Hooks inside loops, conditions, or nested functions. Always use them at the top level of the functional component.
- Only Call Hooks from React Functions:
Ensure that Hooks are called from within React function components or custom Hooks, not regular JavaScript functions.
- Use Hooks in Functional Components Only:
Hooks should only be used in functional components, not in class components. This is a fundamental rule of using Hooks.
- Follow the Naming Convention:
Start custom Hooks with the word "use" to be recognized as Hooks by the linter and other developers. For example,
useCustomHook. - Keep Hooks in the Same Order:
Make sure to call Hooks in the same order on every render to maintain the consistency of the component state.
- Do Not Call Hooks Conditionally:
Do not call Hooks inside if statements or other conditional blocks. Hooks should always be called unconditionally.
- Only Call Hooks from React Components:
Ensure that Hooks are called from within React components or custom Hooks, not from regular JavaScript functions.
- Limit Hook Calls:
Do not call Hooks inside loops or use them excessively within a component. Keep the usage of Hooks limited and focused.
ā Further Reading: Rules of Hook
Q4. What are the benefits of using Hooks over Class Components?
Hooks in React provide several advantages over class components. Here are the following
- Code Reusability: With hooks, you can reuse stateful logic across components without changing the component hierarchy.
- Improved Readability: Hooks allow you to organize and separate concerns in a more readable way compared to class components.
- Reduced Boilerplate: Hooks eliminate the need for writing constructor functions and binding methods, reducing boilerplate code.
- Encourages Functional Programming: Hooks promote the use of functional components, making it easier to adopt functional programming paradigms.
- Improved Performance: Hooks can lead to better performance optimizations since they allow React to avoid unnecessary re-renders.
- Better State Management: Hooks like useState and useContext simplify state management and make it more predictable.
- Custom Hooks: Hooks enable the creation of custom hooks, which encapsulate logic for reuse across different components.
- Compatibility with Future React Features: React is focusing more on functional components and hooks, making them the preferred choice for future compatibility.
Q5. How does React preserve state across renders for Hooks?
React preserves state across renders for Hooks through the use of the useState and useEffect hooks, which are fundamental in managing state and side effects in functional components.
useState Hook
The useState hook allows components to manage state in function components. When a component is rendered, the state values are stored in memory and associated with the specific instance of the component.
When the component re-renders due to changes in state or props, React reconciles the previous state values with the new ones. This reconciliation process ensures that the component retains its state across renders.
useEffect Hook
The useEffect hook enables components to perform side effects, such as fetching data, updating the DOM, or subscribing to external events. It runs after every render and can interact with state and props.
By using the useEffect hook, developers can ensure that their components have consistent behavior across renders, preserving state and managing side effects in a predictable manner.
Example:
import React, { useState, useEffect } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
In this example, the Counter component uses the useState hook to manage the count state. The useEffect hook updates the document title whenever the count state changes.
By leveraging these hooks, React ensures that state is preserved across renders, maintaining the component's internal state consistency and enabling developers to build robust and interactive user interfaces.
Managing State with useState and useReducer
Q6. What is the purpose of the useState hook?
useState is a crucial hook in React that allows functional components to manage state. It provides a way to introduce stateful logic in function components, which were previously stateless. This hook enables you to create and update state variables within functional components.
Key Aspects of the useState Hook:
- useState returns a stateful value and a function to update it.
- When you call useState(initialState), it returns an array. The first element of the array is the current state value, and the second element is a function that lets you update the state.
- useState initializes the state only once when the component is rendered for the first time.
useState Hook Example:
import React, { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
return (
div>
p>Count: {count}/p>
button onClick={() => setCount(count + 1)}>Increase Count/button>
/div>
);
};
In the example above, useState(0) initializes the count state variable with an initial value of 0. The setCount function updates the count state when the button is clicked.
Checkout 8 React Hooks Comparisons
Q7. How does useState trigger a re-render?
useState is a React Hook used to manage state in functional components. When the state value returned by useState is updated, it triggers a rerender of the component where it is used.
Let's look at an example to understand how useState triggers a rerender:
import React, { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
return (
div>
p>Count: {count}/p>
button onClick={increment}>Increment/button>
/div>
);
};
In the above example, we have a Counter component that uses useState to manage the count state. When the Increment button is clicked, the increment function is called, which updates the count state using setCount.
Now, when the count state is updated using setCount, React identifies that the component's state has changed, and it triggers a rerender of the Counter component to reflect the updated state.
This process of updating state and triggering a rerender allows React to efficiently manage the component's UI based on the latest state values.
Q8. Difference between updating state using value setCount(<New value>) vs function updater setCount(prev => prev + 1)?
In summary, using the value directly will replace the state value, while using the function updater allows you to access the previous state.
When updating state in React using useState, there are two ways to update the state: by passing a new value directly or by using a function that receives the previous state value as an argument.
setCount(<New value>): This approach directly sets the state to the new value provided.setCount(prev => prev + 1): This approach uses a function that takes the previous state as an argument and returns the updated state based on the previous state.
Let's understand the difference with an example:
import React, { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
const handleIncrement = () => {
// Using setCount with new value
setCount(count + 1);
};
const handleIncrementWithFunction = () => {
// Using setCount with function updater
setCount(prev => prev + 1);
};
return (
div>
p>Count: {count}/p>
button onClick={handleIncrement}>Increment Count Directly/button>
button onClick={handleIncrementWithFunction}>Increment Count with Function/button>
/div>
);
};
export default Counter;
In this example,
The first button (Increment Count Directly) uses setCount(count + 1) to update the count directly by adding 1 to the current count.
The second button (Increment Count with Function) uses setCount(prev => prev + 1) to update the count by incrementing the previous count value by 1.
Both approaches achieve the same result of incrementing the count by 1, but the function updater method ensures that the state is updated based on the latest state value, avoiding potential inconsistencies in case of concurrent updates.
Q9. What is lazy initialization in useState?
Lazy initialization of useState in React is a technique used to defer the initialization of state values until they are actually needed. This can be beneficial in scenarios where the initial state computation is expensive or relies on props or other state values that may not be readily available.
Here's how you can achieve lazy initialization of useState in React:
Using a function to initialize state:
const [state, setState] = useState(() => {
// Expensive computation or logic here
return initialState;
});
By passing a function as an argument to useState, React will call that function only once to compute the initial state value.
Code Example:
const [count, setCount] = useState(() => {
return props.initialCount * 2;
});
In this example, the initial count is calculated based on the initialCount prop passed to the component, doubling its value.
Q10. Explain useReducer hook.
The useReducer hook is a built-in React hook that is used for managing more complex state logic in functional components. It is an alternative to useState when the state logic involves multiple sub-values or when the next state depends on the previous one.
When using useReducer, you need to specify a reducer function that determines changes to an application's state. The reducer function takes the previous state and an action as arguments and returns a new state based on the action type.
Here is a basic syntax example of using useReducer:
const initialState = { count: 0 };
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
};
const [state, dispatch] = useReducer(reducer, initialState);
Key Points you should know about useReducer Hook:
- Reducer Function: You need to define a reducer function that specifies how state transitions happen based on actions.
- Initial State: You provide an initial state value when calling
useReducer. - Dispatch: The
dispatchfunction is used to dispatch actions to the reducer, triggering state transitions. - Action Types: Actions are plain objects that must have a
typeproperty which specifies the type of action being performed. - Immutable Updates: Reducers must always return new state objects or the same state object if no changes are needed.
Q11. Difference Between useReducer and useState: When to use useReducer over useState
Here is the difference:
useState:
- Used for managing simple state transitions in React components.
- Updates are independent and based on the previous state.
- Good for managing component-level state.
useReducer:
- Used for managing more complex state logic in React components.
- Updates are based on actions dispatched to the reducer function.
- Good for managing global state or state that involves multiple sub-values.
When to Prefer useReducer over useState:
Here is a comparison in table format:
| Criteria | useState | useReducer |
|---|---|---|
| Complex State Logic | Not ideal for complex state logic | Preferred for complex state logic |
| Multiple Sub-Values | Not suitable for managing multiple sub-values | Useful for managing state with multiple sub-values |
| Global State | Not designed for global state management | Recommended for global state management |
| Performance | Simple and straightforward, good for performance | May add unnecessary complexity for simple state |
Handling Side Effects with useEffect:
Q12. Explain how useEffect works.
useEffect is a hook in React that allows functional components to perform side effects. These side effects can be data fetching, subscriptions, or manually changing the DOM in React components.
When using useEffect, you are telling React that your component needs to do something after render. React will remember the function you passed (the effect), and call it after updating the DOM.
Basic Syntax
The basic syntax of useEffect is:
useEffect(() => {
// Effect code
}, [dependencies]);
- Effect code: The function that contains the code you want to run as a side effect.
- Dependencies: An optional array of dependencies. If any of these dependencies change, the effect will re-run.
Example
Here is an example where we fetch data from an API when the component mounts:
import React, { useState, useEffect } from 'react';
const MyComponent = () => {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []); // Empty array means this effect runs only on mount
return (
div>
{data ? p>Data loaded: {data}/p> : p>Loading.../p>}
/div>
);
};
In this example, the effect runs once when the component mounts because the dependency array is empty. It fetches data from an API and updates the state with the fetched data.
Remember to clean up your effects to prevent memory leaks. You can return a function from useEffect that cleans up after the effect. This function will run when the component unmounts or when the dependencies change.
useEffect is a powerful hook in React that allows you to manage side effects in functional components effectively.
Q13. What are the dependency array patterns in useEffect Hook?
Here are the dependency array patterns in useEffect Hook
1. Empty Dependency Array
When the dependency array is empty, the useEffect hook will run only once after the initial render.
2. Dependency Array with Specific Variables
When specific variables are listed in the dependency array, the effect will run whenever any of these variables change. If any of the listed variables change, the effect will be executed.
useEffect(() => {
// Effect code
}, [variable1, variable2]);
3. Dependency Array with No Dependencies
When the dependency array is omitted, the effect will run after every render. This is equivalent to having all state variables as dependencies.
useEffect(() => {
// Effect code
});
4. Dependency Array with Functions
Using functions in the dependency array can lead to unintended behaviors as functions are recreated on every render. It's recommended to use the function inside the effect itself.
useEffect(() => {
const fetchData = () => {
// Fetch data
};
fetchData();
}, [fetchData]); // Incorrect
5. Dependency Array with Cleanup Function
When a cleanup function is needed, it can be included within the effect function. The cleanup function will run before the effect runs again or when the component unmounts.
useEffect(() => {
// Effect code
return () => {
// Cleanup code
};
}, [dependency]);
Q14. How do you handle cleanup in useEffect?
In React, the useEffect hook is used to perform side effects in function components. When working with useEffect, it's important to handle cleanup to avoid memory leaks and unexpected behavior.
Handling Cleanup in useEffect
To handle cleanup in useEffect, you can return a function from the effect. This function will be executed when the component unmounts or when the dependencies of the effect change.
useEffect(() => {
// Perform some side effect
return () => {
// Cleanup code here
};
}, [dependencies]);
The cleanup function returned from useEffect will be called before the component is unmounted. This is useful for cleaning up subscriptions, event listeners, or any resources allocated in the effect.
Example of Cleanup in useEffect
import React, { useEffect } from 'react';
const MyComponent = () => {
useEffect(() => {
const interval = setInterval(() => {
console.log('Hello');
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
return (
div>
p>Component with cleanup in useEffect/p>
/div>
);
};
export default MyComponent;
In the example above, we have a component that sets up an interval in the useEffect. The cleanup function returned clears the interval when the component unmounts or when the dependencies change.
Q15. What is the difference between useEffect and useLayoutEffect?
useEffect:
- Runs after the browser has painted, which means it does not block painting.
- It is asynchronous and runs after the component has rendered.
- It does not hold up painting and is suitable for most side effects like data fetching, subscriptions, etc.
useLayoutEffect:
- Runs synchronously after React has performed all DOM mutations.
- It is a synchronous hook and runs immediately after DOM mutations but before the browser paints.
- Use it when you need to read from the DOM and then synchronously re-render.
Comparison Table
| Aspect | useEffect | useLayoutEffect |
|---|---|---|
| Timing | Asynchronous | Synchronous |
| Execution | After the browser has painted | After all DOM mutations but before painting |
| Use case | Suitable for most side effects | For immediate DOM measurements |
Q16. What are some common pitfalls of useEffect Hook?
Here are the Common pitfalls of the useEffect Hook:
1. Incorrect Dependency Array
One common mistake when using the useEffect Hook is providing an incorrect dependency array. If the dependency array is not properly set, it can lead to unintended behavior such as infinite loops or missing updates.
2. Side Effects Without Cleanup
Another issue is when side effects are performed within the useEffect Hook without implementing proper cleanup. Failing to clean up after side effects can result in memory leaks and performance issues.
3. Multiple useEffect Calls
Having multiple useEffect calls in a component can make the code harder to manage and understand. It's important to organize and consolidate useEffect calls to improve readability and maintainability.
4. Asynchronous Operations
Handling asynchronous operations within the useEffect Hook can be tricky. If not managed correctly, it can lead to race conditions, out-of-order updates, or stale data being displayed.
5. Dependency Warning Suppress
Disabling the warning for missing dependencies in the dependency array of useEffect can hide potential bugs in the code. It's crucial to address and include all necessary dependencies to ensure the proper functioning of the effect.
Performance Optimization Hooks
Q17. How can the useMemo Hook help in performance optimization?
The useMemo Hook in React can significantly help in performance optimization by memoizing the result of expensive calculations and preventing unnecessary re-renders.
How useMemo Works
When using useMemo, you provide a function and a list of dependencies. React will only recompute the memoized value when one of the dependencies has changed. If the dependencies have not changed, React will return the cached value, avoiding unnecessary computations.
Benefits of Using useMemo for Performance Optimization
- Improved Efficiency: By caching the result of a function based on dependencies, useMemo ensures that the calculation is only performed when necessary, reducing unnecessary computations.
- Preventing Unwanted Renders: useMemo helps in preventing unnecessary re-renders of components by providing a cached value if the dependencies have not changed.
- Optimizing Expensive Operations: When dealing with computationally expensive operations such as complex calculations or data processing, useMemo can be used to optimize performance by memoizing the results.
Example of Using useMemo
import React, { useMemo } from 'react';
const Component = ({ data }) => {
const processedData = useMemo(() => {
// Expensive computation or data processing
return processData(data);
}, [data]);
return (
div>
p>Processed Data: {processedData}/p>
/div>
);
};
In this example, the processedData variable will only be recalculated when the data prop changes, thanks to the dependency array [data] passed to useMemo.
Q18. When to use useCallback Hook?
The useCallback Hook in React is used to optimize performance by memoizing functions. It is beneficial when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary re-renders.
Here are some scenarios when you should consider using the useCallback Hook:
- When passing callbacks to child components:
- Using
useCallbackensures that the callback function reference remains constant unless its dependencies change, preventing unnecessary re-renders of child components.
- Using
- Optimizing performance in large applications:
- In applications with many components and complex state management, utilizing
useCallbackcan reduce performance bottlenecks caused by unnecessary re-renders.
- In applications with many components and complex state management, utilizing
- Preventing infinite re-renders:
- When a callback function is defined inline within a component, it creates a new reference on each render, potentially causing infinite re-renders in child components that rely on reference equality.
- Dependencies that rarely change:
- If a callback function relies on dependencies that rarely change, using
useCallbackwith those dependencies specified can optimize performance by memoizing the function.
- If a callback function relies on dependencies that rarely change, using
Here's an example demonstrating the use of the useCallback Hook:
import React, { useState, useCallback } from 'react';
const ParentComponent = () => {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
div>
p>Count: {count}/p>
ChildComponent onClick={handleClick} />
/div>
);
};
const ChildComponent = ({ onClick }) => {
return button onClick={onClick}>Increment Count/button>;
};
In this example, the handleClick function is memoized using useCallback with count as a dependency. This ensures that the handleClick function reference remains stable unless the count state changes, preventing unnecessary re-renders of the ChildComponent.
Q19. What is the difference between useMemo and useCallback?
useMemo and useCallback are both hooks provided by React to optimize performance in functional components by memoizing values or functions. Here is a detailed comparison between the two:
| Feature | useMemo | useCallback |
|---|---|---|
| Caching | Calculates and memorizes a value | Memorizes a function instance |
| Usage | Used to memoize a value to prevent re-calculation | Used to memoize a callback function to prevent re-creation |
| Return Type | Returns the memoized value | Returns the memoized function |
| Dependencies | Recomputes the value when dependencies change | Recreates the function when dependencies change |
| Performance Impact | Reduces unnecessary re-computations | Reduces unnecessary re-creations of functions |
ā Further Reading: useMemo vs useCallback Hook
Q20. Difference between React.memo and useMemo?
React.memo
React.memo is a higher-order component in React that is used for memoizing functional components to prevent unnecessary re-renders.
- It compares the previous props with the new props and re-renders only if there are differences.
- It's useful for optimizing performance in functional components that render the same output for the same input.
- It's similar to PureComponent for class components.
useMemo
useMemo is a hook in React that memoizes the result of a function so that the computation is only done when the dependencies change.
- It accepts a function and an array of dependencies and returns the memoized value.
- It's useful for optimizing performance by caching the result of expensive computations.
- It's used inside functional components to avoid recalculating values on every render.
Comparison Table: React.memo vs useMemo
| Feature | React.memo | useMemo |
|---|---|---|
| Usage | Higher-order component | Hook |
| Optimization | Optimizes component re-renders | Optimizes expensive computations |
| Dependency Tracking | Tracks props changes | Tracks dependencies array changes |
| Return Value | Component | Value |
ā Further Reading: React.memo vs useMemo Hook
Referencing and Context
Q21. What is the useRef hook used for?
The useRef hook in React is used to create a mutable reference that can persist across re-renders of a component. It returns a mutable object whose .current property can hold a value that persists throughout the component's lifecycle.
Example Usage of the useRef Hook
Here is an example demonstrating the use of useRef to focus an input element when a button is clicked:
import React, { useRef } from 'react';
const MyComponent = () => {
const inputRef = useRef(null);
const handleButtonClick = () => {
inputRef.current.focus();
};
return (
div>
input ref={inputRef} type="text" />
button onClick={handleButtonClick}>Focus Input/button>
/div>
);
};
In this example:
- We import
useReffrom 'react'. - We create a
refnamedinputRefinitialized withnull. - When the button is clicked, the
handleButtonClickfunction is triggered, which usesinputRef.currentto focus on the input element. - The input element uses
ref={inputRef}to assign therefto the input element.
Q22. What is the difference between useRef and useState?
useRef and useState are both hooks in React, but they serve different purposes:
| Feature | useRef | useState |
|---|---|---|
| Used for | Accessing DOM nodes or persisting values across renders without causing re-renders | Managing state in functional components |
| Initial Value | Can be initialized with any value | Requires passing an initial state value |
| Re-renders | Changing a ref does not trigger a re-render |
Changing state triggers a re-render |
| Mutable | Mutable (the value can be changed without triggering re-renders) | Immutable (state updates trigger re-renders) |
| Typical Use Case | Accessing input values, focusing elements, animations, etc. | Storing and updating component state |
ā Detailed Explanation: useRef vs useState
Q23. Compare useRef vs createRef Hook in React?
In React, both useRef and createRef are used for creating references to DOM elements or React components. However, there are some differences between the two hooks.
| Feature | useRef Hook | createRef Hook |
|---|---|---|
| Initialization | It is initialized with null. |
It is initialized with React.createRef(). |
| Usage | It is primarily used in functional components. | It is used in class components. |
| Accessing the Ref | Accessed via the current property. |
Accessed by directly accessing the ref. |
| Imperative Methods | Allows mutating the current property imperatively. |
Does not allow mutating the ref imperatively. |
| Updating the Ref | Update the current property directly. |
Update by reassigning the ref to a new value. |
ā Detailed Explanation: useRef vs createRef
Q24. What is the purpose of useContext Hook in React?
In React, the useContext Hook is used to access data or state that is shared across multiple components without having to pass props through every level of the component tree. It allows components to subscribe to a context and re-render when the context value changes.
Benefits of useContext Hook in React:
- Provides a cleaner and more efficient way to pass down data through the component tree.
- Reduces prop drilling, making code more maintainable and readable.
- Helps avoid deeply nested component structures by allowing components to directly access context.
How useContext Hook Works:
When a component uses the useContext Hook, it subscribes to changes in the context value provided by a Provider component higher up in the tree. This allows the component to access the context value directly.
Example Usage of useContext Hook:
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
const ThemeComponent = () => {
const theme = useContext(ThemeContext);
return (
div style={{ background: theme === 'dark' ? 'black' : 'white', color: theme === 'dark' ? 'white' : 'black' }}>
Current Theme: {theme}
/div>
);
};
In this example, the ThemeComponent directly accesses the ThemeContext value using the useContext Hook to render based on the current theme.
Q25. What is the useId hook in React, and explain its use cases?
The useId hook in React is a custom hook that generates a unique identifier. It is useful when you need to create elements dynamically and require a unique identifier for each instance.
Use Cases of useId Hook:
- Generating unique keys for lists or dynamically created components.
- Associating labels with form elements.
Example:
Here is an example of how you can create and use a useId hook:
import { useState } from 'react';
const useId = () => {
const [id, setId] = useState(`id-${Math.random().toString(36).substr(2, 9)}`);
return id;
};
const MyComponent = () => {
const uniqueId = useId();
return (
div>
label htmlFor={uniqueId}>Enter your name:/label>
input id={uniqueId} type="text" />
/div>
);
};
In this example, the useId hook generates a unique identifier using a random string. This identifier is then used to associate the label with the input field in the MyComponent component.
ā Further Reading: Difference between React useId Hook and generating IDs using Math.random?
Custom Hooks & Optimizations
Q26. What are Custom Hooks and when to use Custom Hooks?
Custom Hooks in React are JavaScript functions that allow you to extract component logic into reusable functions. They let you reuse stateful logic between components without changing the component hierarchy.
When to Use Custom Hooks - Custom Hooks can be used in various scenarios:
- Code Reusability: When you find yourself duplicating code across multiple components, custom hooks can help extract that logic into a reusable function.
- Complex State Logic: If your component has complex state management or side effects, custom hooks can encapsulate that logic to keep your components clean.
- Separation of Concerns: Custom hooks promote separation of concerns by allowing you to separate different types of logic into distinct hooks.
Example of a Custom Hook
Here's an example of a simple custom hook for handling dark mode in a React application:
import { useState } from 'react';
function useDarkMode() {
const [isDarkMode, setIsDarkMode] = useState(false);
const toggleDarkMode = () => {
setIsDarkMode((prevMode) => !prevMode);
};
return { isDarkMode, toggleDarkMode };
}
export default useDarkMode;
In this example, the custom hook useDarkMode manages the state of dark mode and provides a function to toggle it.
To use this custom hook in a component:
import React from 'react';
import useDarkMode from './useDarkMode';
function DarkModeToggle() {
const { isDarkMode, toggleDarkMode } = useDarkMode();
return (
div>
button onClick={toggleDarkMode}>Toggle Dark Mode/button>
div>Dark Mode: {isDarkMode ? 'On' : 'Off'}/div>
/div>
);
}
export default DarkModeToggle;
By using this custom hook, you can easily implement dark mode functionality in any component.
Q27. What are the Most Commonly used Custom Hooks in React?
Custom hooks are a powerful feature in React that allows you to extract component logic into reusable functions. Below are 10 commonly used custom hooks in React:
1. UseStateWithLocalStorage
Description: A custom hook that syncs state with local storage.
const [value, setValue] = useStateWithLocalStorage('myKey');
2. UseEffectOnce
Description: A custom hook that runs an effect only once.
useEffectOnce(() => { /* do something */ });
3. UseDebounce
Description: A custom hook that debounces input values.
const debouncedValue = useDebounce(value, 500);
4. UseThrottle
Description: A custom hook that throttles function calls.
const throttledFunction = useThrottle(() => { /* do something */ }, 1000);
5. UseFetch
Description: A custom hook for making API calls.
const { data, loading, error } = useFetch('https://api.example.com/data');
6. UseMediaQuery
Description: A custom hook for handling responsive design.
const isMobile = useMediaQuery('(max-width: 768px)');
7. UseScrollToTop
Description: A custom hook that scrolls to the top of the page on route change.
useScrollToTop();
8. UseDarkMode
Description: A custom hook for adding dark mode functionality.
const isDarkMode = useDarkMode();
9. UseFormValidation
Description: A custom hook for form validation.
const { values, errors, handleChange, handleSubmit } = useFormValidation(validationRules);
10. UseLocalStorage
Description: A custom hook for interacting with local storage.
const [data, setData] = useLocalStorage('myData', initialValue);
ā Further Reading: 20 Most Asked Custom Hooks in React →
Q28. How useTransition and useDeferredValue Hooks help in improving performance?
useTransition and useDeferredValue Hooks in React are essential tools for optimizing the performance of your frontend applications.
useTransition Hook:
The useTransition Hook allows you to defer rendering of certain updates during a state transition. This is particularly useful when dealing with expensive updates that might cause jank or performance issues.
When you wrap a section of your code with useTransition, React will batch updates and only apply them once the transition is complete. This helps in preventing unnecessary re-renders and improves the overall user experience.
useDeferredValue Hook:
The useDeferredValue Hook enables you to defer the update of a value until a certain condition is met. This can be incredibly helpful when you have computations or data fetching operations that are not immediately needed or can be postponed without affecting the user experience.
By using useDeferredValue, you can prioritize rendering of essential parts of your application while delaying non-critical updates until they are required. This can significantly enhance the perceived performance of your app.
How They Improve Performance:
- Reduced Jank: By deferring updates, both hooks help in reducing jank and stuttering in your UI, especially during complex state transitions.
- Optimized Rendering: They optimize rendering by batching updates and rendering only when necessary, leading to a smoother user experience.
- Improved Responsiveness: Prioritizing critical updates over non-critical ones enhances the responsiveness of your application.
Example Usage:
import { useTransition, useDeferredValue } from 'react';
function App() {
const [isPending, startTransition] = useTransition();
const deferredValue = useDeferredValue(someValue, { timeoutMs: 2000 });
return (
div>
button onClick={() => startTransition(() => {
// Perform some state updates or expensive computations
})}>
Trigger Transition
/button>
p>Deferred Value: {deferredValue}/p>
/div>
);
}
By incorporating useTransition and useDeferredValue Hooks in your React applications, you can optimize performance, enhance user experience, and ensure smoother interactions, especially in scenarios where rendering delays or updates can impact usability.
ā Further Reading: Detailed explanation useTransition vs useDeferredValue →
Q29. What are the Hook equivalents of class lifecycle methods in React?
In React functional components, Hooks provide a way to use state, context, and other React features without writing a class. Understanding the equivalents of class lifecycle methods in Hooks is essential for managing component behavior.
| Class Component Lifecycle Method | Hook Equivalent |
|---|---|
| componentDidMount() | useEffect(() => {}, []) |
| componentDidUpdate() | useEffect(() => {}) |
| componentWillUnmount() | useEffect(() => { return () => {} }, []) |
| getDerivedStateFromProps() | useEffect(() => { /* logic here */ }, [props]) |
| shouldComponentUpdate() | useMemo(() => { /* return boolean logic */ }, [deps]) |
Explanation
Let's delve into the details of each Hook equivalent:
- useEffect(() => {}, []): Similar to
componentDidMount(), runs after the first render and only once. - useEffect(() => {}): Equivalent to
componentDidUpdate(), runs after every render. - useEffect(() => { return () => {} }, []): Mimics
componentWillUnmount(), cleans up effects to prevent memory leaks. - useEffect(() => { /* logic here */ }, [props]): Resembles
getDerivedStateFromProps(), updates state based on props changes. - useMemo(() => { /* return boolean logic */ }, [deps]): Replaces
shouldComponentUpdate(), memoizes a value to optimize re-renders.
Q30. Implement custom useThrottle & useDebounce Hooks to improve performance
Frontend developers often encounter scenarios where functions are triggered frequently, such as event handlers for user interactions. In such cases, using throttling and debouncing techniques can significantly improve performance by optimizing how these functions are executed. Let's explore how custom hooks utilizing throttling and debouncing can be implemented to enhance performance.
Throttling Custom Hook
Throttling limits the rate at which a function is executed. It ensures that the function is called at most once in a specified time window. This is particularly useful for actions like scroll events or resizing a window where frequent function calls are not necessary.
Here is an example of a throttle custom hook:
const useThrottle = (callback, delay) => {
const lastRan = useRef(Date.now());
return useCallback((...args) => {
const now = Date.now();
if (now - lastRan.current >= delay) {
callback(...args);
lastRan.current = now;
}
}, [callback, delay]);
};
ā Further Reading: Detailed Explanation of useThrottle Custom Hook →
Debouncing Custom Hook
Debouncing, on the other hand, delays the execution of a function until a certain amount of time has passed since the last invocation. This is useful for scenarios like search inputs where you want to wait for the user to stop typing before triggering a search request.
Below is an example of a debounce custom hook:
const useDebounce = (callback, delay) => {
const timeoutRef = useRef(null);
return useCallback((...args) => {
clearTimeout(timeoutRef.current);
timeoutRef.current = setTimeout(() => {
callback(...args);
}, delay);
}, [callback, delay]);
};
ā Further Reading: Detailed Explanation of useDebounce Custom Hook →
Usage Example
Let's see how you can use these custom hooks in a React component:
const Component = () => {
const handleThrottledClick = useThrottle(() => {
// Your throttled function logic here
}, 1000);
const handleDebouncedChange = useDebounce((value) => {
// Your debounced function logic here
}, 500);
return (
div>
button onClick={handleThrottledClick}>Throttled Click/button>
input type="text" onChange={(e) => handleDebouncedChange(e.target.value)} />
/div>
);
};
By incorporating these custom hooks in your frontend applications, you can effectively improve performance by controlling the frequency of function executions based on specific use cases.
Further Reading š
A seasoned Sr. Engineering Manager at GoDaddy (Ex-Dell) with over 12+ years of experience in the frontend technologies. A frontend tech enthusiast passionate building SaaS application to solve problem. Know more about me š
Learn Next
Featured
100+ Top React JS Interview Questions And Answers
Comments
Be the first to share your thoughts!
No comments yet.
Start the conversation!
Share your expertise
Publish a blog or quick notes on topics you know well ā your write-up could be the answer someone needs before their next frontend interview.
Build your portfolio
Help the community
Sharpen your skills
Earn goodies
Other Related Blogs
8 React Hooks Comparisons: Must Know for Frontend Interviews
Anuj Sharma
Last Updated Jun 24, 2026
Explore the Most Common React Hooks Comparisons and Trade-Offs to understand the differences between Hooks & When to use one hook over another.
Common Pitfalls of useEffect Hook: Must Know for React Devs?
Anuj Sharma
Last Updated Jun 24, 2026
Understand common pitfalls of the useEffect hook when implementing asynchronous operations in React applications effectively.
useMemo vs useEffect Hooks in React: Difference & Trade-Off
Anuj Sharma
Last Updated Jun 24, 2026
Explore useMemo vs useEffect in React with examples. Learn key differences between useMemo and useEffect, use cases, and when to choose one hook over the other in React applications and interviews.
Difference between React useId Hook and generating IDs using Math.random?
Anuj Sharma
Last Updated Jun 24, 2026
Understand the difference between using useId() vs generating IDs using Math.random() to better know the practical use-case of useId Hook in react applications.
useDeferredValue vs useTransition: Difference and Trade-Off
Anuj Sharma
Last Updated Jun 20, 2026
Explore useDeferredValue vs useTransition in React with examples. Learn key differences between useDeferredValue and useTransition, use cases and when to choose one over the other in React applications.
useRef vs useState in React: Difference & Trade-off
Anuj Sharma
Last Updated Jun 19, 2026
Explore useRef vs useState in React with examples. Learn the key differences between useRef and useState, use cases, advantages, and disadvantages, and when to choose one over the other in React applications.
useRef vs createRef in React: Difference and Trade Off
Anuj Sharma
Last Updated Jun 19, 2026
Explore useRef vs createRef in React with examples. Learn the key differences between useRef and createRef, use cases and when to choose one over the other in React applications
useMemo vs useCallback in React: Difference and Trade Off
Anuj Sharma
Last Updated Jun 19, 2026
Explore useMemo vs useCallback in React with examples. Learn the key differences between useMemo and useCallback, use cases, and when to choose one over the other in React applications.
