Advanced Level React Interview Questions & Answers – Set 1
1. What are Server Components in React 18? How do they differ from Client Components?
-
Server Components: These run on the server, not in the browser.
They don’t send JavaScript to the client, which reduces bundle size and improves performance.
-
Client Components: These run in the browser, handle interactions like clicks, inputs, animations, etc.
Key Difference:
Server Components cannot use hooks like useState or useEffect because they don’t run in the browser. They are mainly for rendering static or data-heavy UI.
Example:
// Server Component (fetching data from DB)
export default async function Products() {
const data = await getProductsFromDB();
return (
<ul>
{data.map(p => <li key={p.id}>{p.name}</li>)}
</ul>
);
}
// Client Component (handling clicks)
"use client";
export default function Button() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>Clicked {count}</button>
}
2. What are Compound Components in React, and why are they useful?
- Compound Components let you build a parent component with flexible children that share implicit state.
- They are useful when you want a reusable, customizable component with controlled parts.
Example (Tabs):
function Tabs({ children }) {
const [active, setActive] = React.useState(0);
return React.Children.map(children, (child, index) =>
React.cloneElement(child, { active, setActive, index })
);
}
function Tab({ index, setActive, active, children }) {
return (
<buttonstyle={{ fontWeight: active === index ? "bold" : "normal" }}
onClick={() => setActive(index)}
>
{children}
</button>
);
}
function TabPanel({ index, active, children }) {
return active === index ? <div>{children}</div> : null;
}
// Usage
<Tabs>
<Tab>Home</Tab>
<Tab>Profile</Tab>
<TabPanel>Home Content</TabPanel>
<TabPanel>Profile Content</TabPanel>
</Tabs>
3. How does the Render Props pattern differ from HOCs? Which one is preferable?
- Render Props: Pass a function as a child to share logic.
- HOC (Higher Order Component): Wrap a component to inject extra props.
Today, Hooks are preferred because they are simpler and more readable.
Example (Render Props):
function MouseTracker({ render }) {
const [pos, setPos] = React.useState({ x: 0, y: 0 });
return (
<div onMouseMove={e => setPos({ x: e.clientX, y: e.clientY })}>
{render(pos)}
</div>
);
}
// Usage
<MouseTracker render={({ x, y }) => <h1>Mouse at {x}, {y}</h1>} />
4. What is the difference between controlled context propagation and normal context?
- Normal Context: Every consumer re-renders when context changes.
- Controlled Context Propagation (React 18): Lets you control which parts should update, avoiding unnecessary re-renders.
Example: In a big form, only re-render the changed field, not the entire form.
5. How would you design a large-scale React app for maintainability?
Use these practices:
- Folder by feature (not by file type).
- Atomic components (small reusable pieces).
- State management (Redux, Zustand, Recoil).
- Lazy loading & code splitting.
- TypeScript for safety.
- Testing with Jest/RTL.
6. Explain the reconciliation algorithm in React.
- React compares the old virtual DOM vs new virtual DOM.
- If something changed, React updates only that part (diffing).
- Keys help React identify which list items changed.
7. What is the Fiber architecture in React?
- Fiber = new rendering engine (since React 16).
- It breaks rendering into small units of work so React can pause and continue (like multitasking).
- Improves performance for large apps.
8. How does Concurrent Rendering work in React 18?
- React can pause, interrupt, and resume rendering.
- This means smooth UI (no blocking).
- Example: Typing in a search box while results update in background.
9. What is Automatic Batching in React 18?
- Before: Only React events were batched.
- Now: All updates (timeouts, promises, async code) are batched → fewer re-renders → faster app.
Example:
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React batches these into one render in React 18
}, 1000);
10. How do you optimize performance with virtualization?
- Virtualization = Render only visible items, not all at once.
- Libraries: react-window, react-virtualized.
Example:
import { FixedSizeList as List } from "react-window";
<Listheight={400}
itemCount={10000}
itemSize={35}
width={300}
>
{({ index, style }) => <div style={style}>Row {index}</div>}
</List>
11. What are the two main phases of React Fiber?
- Render Phase → Build virtual DOM (can be paused).
- Commit Phase → Apply changes to real DOM (fast, can’t be paused).
12. How does React implement event delegation internally?
- React uses a single event listener on the root.
- Events bubble up, React finds which component should handle it.
- Improves performance instead of attaching events everywhere.
13. What is a render pipeline in React?
- Trigger update (setState).
- Render phase (build virtual DOM).
- Diffing & reconciliation.
- Commit phase (update DOM).
14. How would you avoid unnecessary re-renders with useContext?
- Problem: Whole tree re-renders.
- Solution:
- Split context.
- Use
useMemo. - Use selectors (like Zustand/Recoil).
15. Difference between useLayoutEffect and useEffect?
- useEffect: Runs after paint → async, non-blocking.
- useLayoutEffect: Runs before paint → blocks screen → used for DOM measurements.
16. Pitfalls of useMemo & useCallback?
- Overusing them makes code slower.
- Use only when heavy calculation or function passed to child.
17. Custom Hook for Debouncing Input
function useDebounce(value, delay) {
const [debounced, setDebounced] = React.useState(value);
React.useEffect(() => {
const handler = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debounced;
}
// Usage
const search = useDebounce(query, 500);
18. Global State with useReducer + Context
const StateContext = React.createContext();
function reducer(state, action) {
switch (action.type) {
case "add": return { ...state, count: state.count + 1 };
default: return state;
}
}
export function StateProvider({ children }) {
const [state, dispatch] = React.useReducer(reducer, { count: 0 });
return <StateContext.Provider value={{ state, dispatch }}>
{children}
</StateContext.Provider>
}
export function useAppState() {
return React.useContext(StateContext);
}
19. Compare Redux, MobX, Recoil, Zustand
- Redux: Predictable, strict, best for large apps.
- MobX: Easy, reactive, less boilerplate.
- Recoil: Works great with React, atom-based.
- Zustand: Simple, minimal, fast.
20. Client State vs Server State
- Client state: UI-only (dark mode, form values).
- Server state: Fetched from API, needs caching (React Query, SWR).
21. Handling Real-time Data (WebSockets)
- Use
useEffectto open socket. - Update state when message comes.
- Cleanup on unmount.
22. Selectors in Redux
- Selectors are functions to read specific slices of state.
- Improve performance because only the needed part re-renders.
Example:
const selectUser = (state) => state.user;
const user = useSelector(selectUser);
