Skip to main content

React Basics- Interview Questions

 

1. React Basics

Q1: What is the Virtual DOM, and how does it work?

A: The Virtual DOM is a lightweight JavaScript representation of the actual DOM. React uses it to optimize UI rendering. When the state of a component changes:

  1. A new Virtual DOM tree is created.
  2. React compares it with the previous Virtual DOM (diffing).
  3. React updates only the changed parts in the real DOM (reconciliation).
    This process improves performance because direct DOM manipulations are slow.

Q2: What is the difference between functional and class components?

A:

FeatureFunctional ComponentClass Component
SyntaxUses functions                        Uses ES6 classes
StateUses useState, useReducerUses this.state
LifecycleUses hooks (useEffect)Uses lifecycle methods (componentDidMount)
PerformanceMore optimizedSlightly heavier
This keywordNot requiredRequires this

Functional components with hooks are preferred due to their simpler syntax and performance benefits.


Q3: What are React hooks, and why were they introduced?

A: Hooks allow functional components to use state and lifecycle features without writing class components.

  • Introduced in React 16.8 to simplify state management and lifecycle logic.
  • Examples:
    • useState → Manages state in functional components.
    • useEffect → Handles side effects (API calls, event listeners).
    • useContext → Accesses global state without prop drilling.
    • useMemo, useCallback → Optimize performance.

2. React State Management

Q4: What is the difference between useState and useReducer?

A:

FeatureuseStateuseReducer
Use Case            Simple state updatesComplex state logic
Syntaxconst [state, setState] = useState(initialValue);    const [state, dispatch] = useReducer(reducer, initialState);
ReducerNot neededRequires a reducer function
PerformanceMay lead to unnecessary re-rendersOptimized for multiple state updates

Example of useReducer:

const reducer = (state, action) => { switch (action.type) { case "increment": return { count: state.count + 1 }; case "decrement": return { count: state.count - 1 }; default: return state; } }; const [state, dispatch] = useReducer(reducer, { count: 0 });

Q5: What is Context API, and how does it work?

A: The Context API is a built-in state management tool in React to avoid prop drilling.

  • Uses React.createContext() to create a global state.
  • Provider wraps components and provides state.
  • useContext consumes the context.

Example:


const ThemeContext = React.createContext("light"); function App() { return ( <ThemeContext.Provider value="dark"> <Child /> </ThemeContext.Provider> ); } function Child() { const theme = useContext(ThemeContext); return <p>Current theme: {theme}</p>; }

This avoids passing props manually at each level.


3. React Performance Optimization

Q6: How can you optimize React app performance?

A:

  • Use React.memo() to prevent unnecessary re-renders.
  • Use useMemo() and useCallback() for expensive computations.
  • Implement lazy loading using React.lazy() and Suspense.
  • Avoid updating the state unnecessarily.
  • Use the Production build (npm run build).
  • Optimize images and assets.

Example of React.memo():


const MemoizedComponent = React.memo(({ value }) => { console.log("Rendering..."); return <p>{value}</p>; });

Prevents re-render if value does not change.


Q7: What is the difference between useMemo and useCallback?

A:

FeatureuseMemouseCallback
Purpose                Memoizes computed values    Memoizes functions
ReturnsA memoized value    A memoized function
When to UseAvoid expensive recalculations    Prevent function re-creation in child components

Example of useMemo:

jsx
const expensiveValue = useMemo(() => computeExpensiveValue(count), [count]);

Example of useCallback:

const memoizedCallback = useCallback(() => { doSomething(); }, [dependency]);

4. React Lifecycle & Side Effects

Q8: What are the different phases of the React component lifecycle?

A:
For Class Components:

  1. Mountingconstructor(), render(), componentDidMount()
  2. UpdatingshouldComponentUpdate(), componentDidUpdate()
  3. UnmountingcomponentWillUnmount()
  4. Error HandlingcomponentDidCatch()

For Functional Components, use useEffect:

useEffect(() => { console.log("Component Mounted"); return () => console.log("Component Unmounted"); }, []);

Q9: What is the difference between useEffect with an empty dependency array and without?

A:

useEffect(() => {...}, [])useEffect(() => {...})
Runs only once after the component mounts         Runs after every render
Used for API calls, event listeners         Used for debugging or logging
Example: Fetch data on mount               Example: Log every state update

Example:

useEffect(() => { console.log("Runs only once!"); }, []);

5. React Advanced Topics

Q10: How does React handle error boundaries?

A:

  • Error boundaries catch JavaScript errors in components and prevent app crashes.
  • Implemented using componentDidCatch(error, info) in class components.

Example:

class ErrorBoundary extends React.Component { state = { hasError: false }; static getDerivedStateFromError() { return { hasError: true }; } componentDidCatch(error, info) { console.error("Error:", error, info); } render() { return this.state.hasError ? <h2>Something went wrong.</h2> : this.props.children; } }

Wrap components inside <ErrorBoundary>...</ErrorBoundary> to handle errors.


6. React Testing

Q11: How do you test React components?

A:

  • Use Jest (testing framework) and React Testing Library.
  • Write unit tests and integration tests.
  • Example test using @testing-library/react:
import { render, screen } from "@testing-library/react"; import MyComponent from "./MyComponent"; test("renders a text", () => { render(<MyComponent />); expect(screen.getByText("Hello World")).toBeInTheDocument(); });

Comments