✅ 1. Fundamentals: JSX, Components, Rendering
Q1: What is JSX and how does it work under the hood?
A: JSX is a syntax extension for JavaScript that looks similar to HTML. It is transpiled by tools like Babel into React.createElement() calls. These calls create JavaScript objects that represent the virtual DOM, which React uses to determine what to render on the screen.
Q2: What is the virtual DOM and how does React use it?
A: The virtual DOM is a lightweight JavaScript representation of the actual DOM. React creates a virtual DOM tree, and when state or props change, it performs a diff between the new and previous tree. It then efficiently updates only the changed parts in the real DOM, improving performance.
Q3: What is reconciliation in React?
A: Reconciliation is the process React uses to update the DOM when a component’s state or props change. React compares the new virtual DOM with the previous one and calculates the minimal number of operations required to update the real DOM, ensuring efficient rendering.
✅ 2. Component Design: Declarative Thinking, Props, State
Q4: What is the difference between props and state?
A: Props are read-only data passed from a parent to a child component. State is managed within a component and can change over time. Props make components reusable and configurable; state determines component behavior.
*Q5: * What does "thinking declaratively" mean in React?
A: Declarative programming means describing what the UI should look like for a given state rather than how to change it. For example, instead of manually manipulating the DOM, you update the state, and React updates the UI accordingly.
Q6: How would you design a reusable component?
A: I'd focus on abstraction through props, avoiding side effects, and using children or render props for flexibility. I'd separate concerns by keeping logic in custom hooks or higher-order components, and I'd document inputs and expected outputs clearly.
✅ 3. React Hooks
Q7: What are the rules of hooks?
A: Hooks must be called:
Only inside React function components or custom hooks.
At the top level of your component (not inside loops, conditions, or nested functions).
These rules ensure hooks run in the same order on every render, which is essential for React to track state and effects correctly.
Q8: What causes infinite loops in useEffect?
A: Infinite loops occur when the useEffect dependency array includes a variable that changes on every render (like a non-memoized function or object). To fix this, you should either memoize dependencies (with useCallback or useMemo) or ensure they don't change unnecessarily.
Q9: When would you use useReducer over useState?
A: useReducer is useful for managing complex state logic involving multiple sub-values or when the next state depends on the previous one. It’s also preferable when the state logic needs to be reused or tested separately.
✅ 4. Controlled vs Uncontrolled Components
Q10: What is the difference between controlled and uncontrolled components?
A: A controlled component's value is managed by React state via props and onChange. An uncontrolled component maintains its own internal state and uses refs to access DOM elements. Controlled components are preferred for form validation and integration with state management.
Q11: When would you use an uncontrolled component?
A: Use uncontrolled components when quick form input capture is needed without two-way data binding, such as file uploads or simple, non-validated forms where performance is more important than real-time control.
✅ 5. Event Handling in React
Q12: How does React handle events differently from the DOM?
A: React wraps native events in a synthetic event system that standardizes behavior across browsers. It also implements event delegation at the root level to improve performance, attaching a single event listener to the root instead of each element.
Q13: Why might event handlers behave differently in class vs function components?
A: In class components, this must be bound manually or using arrow functions. In function components, hooks and closures are used, which can introduce issues like stale closures if not handled correctly.
✅ 6. Common Pitfalls
Q14: What is a stale closure in React hooks?
A: A stale closure occurs when a function inside useEffect or an event handler captures outdated state due to closure behavior. You can avoid this using the useRef hook or ensuring the latest values are in the dependency array.
Q15: What causes unnecessary re-renders? How do you avoid them?
A: Causes include:
Passing new object or function references as props
Updating state unnecessarily
Not memoizing expensive components
Solutions:
Use React.memo, useMemo, and useCallback
Avoid setting state to the same value
Use selectors or memoized props
✅ 7. Performance Optimizations
Q16: How does React.memo work?
A: React.memo is a higher-order component that memoizes the rendered output of a component if its props haven't changed. It prevents unnecessary re-renders by shallow comparing previous and next props.
Q17: What is code-splitting and how do you implement lazy loading?
A: Code-splitting divides your app into smaller chunks so users load only what they need. You can implement lazy loading with:
const LazyComponent = React.lazy(() => import('./LazyComponent'));
and render it using <Suspense fallback={<Loader />}>
.
Q18: How do you use the React Profiler to identify performance issues?
A: React Profiler (in React DevTools) shows the time each component took to render and why it re-rendered. You can use it to detect unnecessary renders and optimize them with memoization or better state management.
Top comments (0)