30 Advanced React Interview Questions and Answers with Code Examples
React is one of the most popular JavaScript libraries for building scalable, efficient, and dynamic user interfaces. If you're preparing for interviews or building large-scale applications, mastering React concepts is critical. This article answers 30 advanced React questions with detailed explanations and examples, making it a developer-friendly resource.
1. Limitations of React in Large-Scale Applications
React is powerful but has some challenges in large enterprise apps:
- No built-in state management for global data. Requires Redux, MobX, or Context.
- Needs third-party libraries for routing, SSR, forms, and API handling.
- Potential rendering bottlenecks in very large component trees.
- Steep learning curve due to Hooks, Fiber, and ecosystem complexity.
2. How React Manages the Virtual DOM
React uses the Virtual DOM to make UI updates more efficient:
- On state change, React creates a lightweight copy of the DOM tree.
- It runs a diffing algorithm to compare old vs new.
- Only changed nodes are updated in the real DOM.
Benefits: Better performance, fewer direct DOM manipulations, smoother UI.
React JSX1function Counter() {
2 const [count, setCount] = React.useState(0);
3
4 return (
5 <button> setCount(count + 1)}>
6 Count: {count}
7 </button>
8 );
9}
3. Can Hooks Replace Redux?
- Hooks + Context API handle local and medium-sized shared state well.
- Redux offers stricter state management, debugging tools, middleware, and better scalability.
Conclusion: Hooks don’t fully replace Redux for enterprise-grade apps.
4. Best Practices for State Management
- Keep local UI state inside components (
useState). - Store global data in Context API or Redux.
- Use libraries like Zustand or Jotai for cleaner global state management.
- Avoid overusing Context because it triggers global re-renders.
5. Optimizing Performance in Large React Apps
- Use
React.memoanduseMemohooks to prevent unnecessary renders. - Implement code splitting with
React.lazy. - Virtualize long lists using react-window.
- Use the Profiler API to identify slow renders.
6. React Strict Mode
StrictMode helps during development by:
- Identifying side-effect issues.
- Alerting on deprecated methods.
- Double-invoking functions in dev mode to highlight unexpected behavior.
React JSX
7. Preventing Unnecessary Re-renders
- Wrap components with
React.memo. - Use
useCallbackto memoize functions. - Pass stable props to children.
React JSX1const Button = React.memo(({ onClick }) => {
2 console.log('Button re-rendered');
3 return <button>Click</button>;
4});
8. Functional vs Class Components
- Functional Components: Cleaner, Hooks-driven, easier testing.
- Class Components: Legacy lifecycle methods, more verbose.
Today, functional components are preferred.
9. Significance of React Fiber
Fiber is React’s reconciliation engine allowing:
- Incremental rendering.
- Task prioritization.
- Efficient updates for large apps.
10. Handling Side Effects in React
React handles side effects with useEffect.
React JSX1useEffect(() => {
2 const fetchData = async () => {
3 const res = await fetch('/api/data');
4 const data = await res.json();
5 console.log(data);
6 };
7 fetchData();
8}, []);
Best practice: use cleanup to avoid memory leaks.
11. Difference Between useMemo and useCallback
useMemo: Memoizes computed values.useCallback: Memoizes functions.
React JSX1const memoizedValue = useMemo(() => expensiveCalc(num), [num]);
2const memoizedFn = useCallback(() => doSomethingWith(val), [val]);
12. Dynamic Form Handling and Validation
React JSX1function Form() {
2 const [form, setForm] = React.useState({ name: "", email: "" });
3
4 const handleChange = (e) =>
5 setForm({ ...form, [e.target.name]: e.target.value });
6
7 return (
8 <form>
9 <input value="{form.name}">
10 <input name="email" value="{form.email}">
11 </form>
12 );
13}
Use libraries like React Hook Form for better validation.
13. Lazy Loading in React
React JSX1const Profile = React.lazy(() => import('./Profile'));
2
3function App() {
4 return (
5 Loading...}>
6
7
8 );
9}
Improves performance by reducing initial bundle size.
14. Error Handling with Error Boundaries
React JSX1class ErrorBoundary extends React.Component {
2 state = { hasError: false };
3
4 static getDerivedStateFromError() {
5 return { hasError: true };
6 }
7
8 render() {
9 if (this.state.hasError) return <h1>Something went wrong.</h1>;
10 return this.props.children;
11 }
12}
Error boundaries catch runtime errors and show fallback UI.
15. Benefits of SSR
- Faster first paint.
- Better SEO.
- Useful for content-heavy apps.
Next.js simplifies SSR in React.
16. Styling in React Components
- CSS Modules example:Plain Text
1jsx 2import styles from './Button.module.css'; 3<button>Click</button> - CSS-in-JS: styled-components.
- Utility-first frameworks: TailwindCSS.
17. Passing Data Between Sibling Components
- Use parent state and pass props down.
- Use Context API when scaling.
18. useEffect for API Fetching
React JSX1useEffect(() => {
2 async function getData() {
3 let res = await fetch("/api");
4 let data = await res.json();
5 console.log(data);
6 }
7 getData();
8}, []);
19. Handling Async Operations
Wrap async calls in try/catch and manage loading states:
React JSX1const [loading, setLoading] = useState(true);
2useEffect(() => {
3 async function fetchData() {
4 try {
5 const data = await getApi();
6 console.log(data);
7 } catch (e) {
8 console.error(e);
9 } finally {
10 setLoading(false);
11 }
12 }
13 fetchData();
14}, []);
20. Re-render on Window Resize
React JSX1const [width, setWidth] = useState(window.innerWidth);
2
3useEffect(() => {
4 const handleResize = () => setWidth(window.innerWidth);
5 window.addEventListener("resize", handleResize);
6 return () => window.removeEventListener("resize", handleResize);
7}, []);
21. Context API for State Management
React JSX1const ThemeContext = React.createContext();
2
3function App() {
4 return (
5
6
7
8 );
9}
22. React Router and Dynamic Routing
React JSX} />
React Router allows single-page navigation with parameters.
23. Controlled vs Uncontrolled Components
- Controlled:
valuemanaged by state. - Uncontrolled: DOM manages value via
ref.
React JSX<input type="text" value="{value}"> setValue(e.target.value)} />
24. Optimizing Large Lists
Use react-window for virtualization:
React JSX1import { FixedSizeList as List } from "react-window";
2
3
4 {({ index, style }) => <div style="{style}">Row {index}</div>}
25. Shallow vs Deep Comparison
- Shallow: Compares references.
- Deep: Compares nested properties.
React uses shallow compare inshouldComponentUpdate.
26. Handling Async State Updates
Use functional updates when working with prior state:
React JSXsetCount(prev => prev + 1);
27. Implementing Custom Hooks
React JSX1function useToggle(initial = false) {
2 const [state, setState] = useState(initial);
3 const toggle = () => setState(!state);
4 return [state, toggle];
5}
28. Higher-Order Components (HOC)
React JSX1function withLogger(Component) {
2 return function Wrapped(props) {
3 console.log("Props: ", props);
4 return ;
5 };
6}
29. Search with Debouncing
React JSX1function useDebounce(value, delay) {
2 const [debounced, setDebounced] = useState(value);
3 useEffect(() => {
4 const handler = setTimeout(() => setDebounced(value), delay);
5 return () => clearTimeout(handler);
6 }, [value, delay]);
7 return debounced;
8}
30. React Reconciliation Process
React’s reconciliation:
- Uses diffing algorithm to compare old vs new VDOM.
- Only updates changed nodes in the actual DOM.
- Optimizes rendering for performance.
This article gives a complete React interview prep guide with answers, examples, and code snippets for every important React concept.