React.js

13 essential react.js interview questions

Class Component (Old way): - Old way of writing React components - Uses lifecycle methods like componentDidMount, componentDidUpdate, componentWillUnmount - More code, complex syntax - Uses "this" keyword to access state and props Functional Component (Modern way): - New and modern way of writing React components - Uses hooks instead of lifecycle methods - Less code, simple and clean syntax - No "this" keyword needed - Returns JSX (HTML like syntax) Functional components are now preferred because they are simpler, more readable, and hooks provide powerful features with cleaner code.
React component has 3 lifecycle stages — Mount, Update, and Unmount. Mounting – when the component is created and added to the DOM. Updating – when state or props change and the component re-renders. Unmounting – when the component is removed from the DOM. For Example: Counter Application - When the component loads for the first time, it enters the Mounting phase. - When the user clicks the Increment button, the state changes, causing the component to re-render. This is the Updating phase. - When the user navigates away and the component is removed from the screen, it enters the Unmounting phase. In functional components, we handle these lifecycle events using the useEffect hook.
Hooks are special functions that let us use state and lifecycle features inside functional components. Common Hooks: useState() - Stores and manages data inside a component. When data changes, the component re-renders with the new value. useEffect() - Runs side effects after component renders. Used for API calls, subscriptions, timers, and DOM updates. Takes a dependency array to control when it runs. useRef() - Gives direct reference to a DOM element. Does not cause re-render when value changes. Useful for focusing inputs or accessing DOM directly. useMemo() - Caches result of heavy calculations so it doesn't recalculate on every render. Only recalculates when dependencies change. Improves performance. useCallback() - Caches a function so it doesn't get recreated on every render. Used when passing functions to child components to prevent unnecessary re-renders. useContext() - Used to share data globally across components without prop drilling. Creates a centralized data store accessible from any component. useReducer() - Used to manage complex state logic. Alternative to useState when state has multiple values or complex updates. Takes a reducer function and initial state.
React Router is a library for client-side routing. Use <BrowserRouter> to wrap app, <Routes> for routes, <Route path="/" element={<Home />} />. Link for navigation without page reload. useParams() and useNavigate() hooks access dynamic routes and navigate programmatically. React Router enables single-page applications with multiple views.
Controlled component: React state manages form value. onChange updates state, input value comes from state. Uncontrolled component: DOM manages value directly using useRef. getValue from ref when needed. Controlled components are predictable, easier to validate. Use controlled for most cases.
A Higher Order Component is a function that takes a component and returns a new component with additional props or behavior. HOCs are used to reuse component logic, such as adding authentication, data fetching, or styling. To reuse common logic across multiple components without duplicating code.

SSR — Server Side Rendering

HTML is built on the server for every request. Server fetches data, generates complete HTML, and sends it to browser. What happens when you visit a page: You open flipkart.com/product/123 Server fetches product data from DB Server builds complete HTML with product details Sends that ready HTML to browser Page appears immediately with content You notice: Page loads with content instantly, no white screen Advantage: Fast first load Google bot gets full HTML — great SEO Always fresh data Disadvantage: Every user visit = server does work again High traffic = server gets overloaded Costly servers needed

CSR — Client Side Rendering

HTML is built in the browser. Server only sends JavaScript, browser does everything else. What happens when you visit a page: You open amazon.com/products Server sends an empty HTML + big JS file Browser downloads JS, runs it JS calls API to fetch products Products appear on screen You notice: Page takes 2-3 seconds, white screen in between Advantage: After first load, clicking other pages feels instant Very interactive UI possible Disadvantage: First load is slow — white screen visible Google bot visits, sees empty HTML — bad SEO Slow on low-end phones

SSG — Static Site Generation

HTML is built at build time — once. Server just stores and serves those pre-built HTML files to every user. What happens when you visit a page: Developer runs npm run build At that moment, server builds HTML for all pages and saves them You open myblog.com/post/how-to-learn-react Server just sends that pre-saved HTML file Page appears instantly You notice: Blazing fast, feels like opening a file Advantage: Fastest possible load Best SEO Can host on CDN — very cheap Server does almost nothing Disadvantage: If blog post is edited, you must rebuild entire project Not suitable for real-time or user-specific data

ISR — Incremental Static Regeneration

SSG but with automatic background refresh. Pages are pre-built like SSG, but after a set time interval server quietly regenerates them with fresh data. What happens when you visit a page: Developer sets revalidate = 60 (60 seconds) First build happens — HTML saved like SSG You visit swiggy.com/restaurant/pizza-hut — get fast pre-built HTML In background, after 60 seconds server quietly rebuilds that page with fresh data Next visitor gets updated HTML You notice: Page loads fast, but price or rating might be 60 seconds old — that's acceptable Advantage: Fast like SSG Data stays fresh automatically No full rebuild needed Best SEO Disadvantage: Not real-time — slight delay in data First visitor after update still sees old data
Virtual DOM is a lightweight copy of the real DOM kept in memory. React uses it to update the UI efficiently without touching the real DOM directly. Process: 1. When state changes, React creates a new Virtual DOM 2. React compares new Virtual DOM with old Virtual DOM - this is called "diffing" 3. React finds only the changed parts 4. React updates only those changed parts in the real DOM - this is called "reconciliation" Benefits: - Makes React much faster than directly manipulating the real DOM - Reduces browser reflows and repaints - Batches DOM updates for better performance - Allows React to optimize which components need to re-render This is why React is efficient even with complex UIs and frequent state changes.
useEffect runs side effects after component renders. The dependency array controls when it runs: empty array = once on mount only, no array = after every render, specific dependencies = only when those dependencies change. Return a cleanup function to prevent memory leaks. useEffect essentially combines componentDidMount + componentDidUpdate + componentWillUnmount.
React.memo prevents re-render if props haven't changed. Wraps component: const MyComponent = React.memo(Component). Performs shallow comparison of props. Useful for expensive computations. Can pass custom comparison function: React.memo(Component, (prevProps, nextProps) => equals).
Error boundary is a class component that catches errors in child components. Prevents entire app from crashing. Implement: componentDidCatch(error, errorInfo) and getDerivedStateFromError(error). Wraps risky components: <ErrorBoundary><Component /></ErrorBoundary>. Shows fallback UI on error. Functional components can't be error boundaries yet.
```text When I optimize a React app, I focus on 5 things: 1. Render performance - React.memo to avoid unnecessary re-renders - useMemo to cache expensive calculations - useCallback to keep function references stable 2. Loading performance - Lazy loading and code splitting - Suspense with fallback UI - Proper loading states instead of blank screens 3. List performance - Pagination for large data sets - Infinite scroll when needed - Windowing or virtualization for huge lists 4. Asset optimization - Image optimization - CDN for static assets - Smaller bundle size and fewer unnecessary assets 5. Data performance - Debouncing for search inputs - API response caching - Use SSG or ISR when the page does not need real-time data So in short, I reduce unnecessary renders, load only what is needed, and cache wherever it makes sense. That gives me a faster UI and a better user experience. ```
Use controlled components: state tracks input values, onChange updates state. Handle submit with onSubmit. Validate before submission. Use libraries like Formik or React Hook Form for complex forms. They handle validation, error messages, and submission. For simple forms, manual state management works fine.