# React Interview - Advanced

1. **<mark>How do you handle data persistence in a React application?</mark>**  
    Data persistence in a React application refers to retaining user data or application state even after a page reload or when navigating away from the page. There are several strategies to achieve this, depending on the scope and requirements of the app,  
    ***i) Local Storage / Session Storage***  
    **Local Storage:** Persists even after the browser is closed.  
    **Session Storage:** Clears when the browser tab is closed.
    
    ```javascript
    // Save to local storage
    localStorage.setItem('user', JSON.stringify(user));
    
    // Retrieve from local storage
    const user = JSON.parse(localStorage.getItem('user'));
    ```
    
    ```javascript
    useEffect(() => {
      const savedUser = localStorage.getItem('user');
      if (savedUser) {
        setUser(JSON.parse(savedUser));
      }
    }, []);
    
    useEffect(() => {
      localStorage.setItem('user', JSON.stringify(user));
    }, [user]);
    ```
    
    ***ii) Cookies***  
    Best for: Small pieces of data, often used for authentication tokens
    
    Can be configured to persist and be sent with HTTP requests.
    
    Can be made secure and HTTP-only.
    
    ```javascript
    document.cookie = "token=abc123; path=/; max-age=3600";
    ```
    
    Use libraries like `js-cookie` for easier management.  
    ***iii) State Management + Persistence Libraries***  
    Redux + redux-persist
    
    Recoil + localStorage integration
    
    Zustand + middleware
    
    ```javascript
    import { persist } from 'zustand/middleware';
    
    const useStore = create(
      persist(
        (set) => ({
          count: 0,
          increase: () => set((state) => ({ count: state.count + 1 })),
        }),
        { name: 'counter-storage' } // stored in localStorage
      )
    );
    ```
    
2. **<mark>What are render props in React?</mark>**  
    **Render props** is a pattern in React that allows you to **share code between components** using a **function as a prop**.  
    A **render prop** is a **function prop** that a component uses to determine **what to render**.  
    To make a component **more reusable and flexible**, by letting the consumer decide **what to render** based on the internal state or logic of the component.
    
    ```javascript
    // DataProvider.js
    import React from 'react';
    
    class DataProvider extends React.Component {
      state = { data: 'Hello from DataProvider' };
    
      render() {
        return this.props.render(this.state);
      }
    }
    ```
    
    ```javascript
    // App.js
    <DataProvider render={(state) => (
      <h1>{state.data}</h1>
    )} />
    ```
    
    i) This pattern is flexible but can get **verbose or messy** if overused.
    
    ii) **Hooks** (like `useState`, `useEffect`, and custom hooks) have largely replaced the need for render props in many cases.
    
    iii) Still useful in class components or third-party libraries.
    
3. **<mark>What are the different optimization techniques used in React Application?</mark>**  
    Optimizing a React application is essential for improving performance, responsiveness, and user experience. Here are the most commonly used **optimization techniques** in React,  
    ***i) Code Splitting***  
    Break your app into smaller bundles so users don't need to load everything at once.  
    React.lazy + Suspense
    
    ```javascript
    const LazyComponent = React.lazy(() => import('./MyComponent'));
    
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
    ```
    
    Use **dynamic imports** with Webpack or tools like **Vite**.  
    ***ii) Memoization***  
    Avoid unnecessary re-renders of components and functions.  
    **React.memo** (for components)
    
    ```javascript
    const MyComponent = React.memo(({ value }) => {
      return <div>{value}</div>;
    });
    ```
    
    **useMemo** (for expensive calculations)
    
    ```javascript
    const computedValue = useMemo(() => expensiveFunction(data), [data]);
    ```
    
    **useCallback** (to memoize event handlers)
    
    ```javascript
    const handleClick = useCallback(() => {
      doSomething();
    }, []);
    ```
    
    ***iii) Virtualization***  
    Render only visible items in large lists/tables. Use libraries like **react-window** or **react-virtualized**
    
    ```javascript
    import { FixedSizeList as List } from 'react-window';
    
    <List
      height={300}
      itemCount={1000}
      itemSize={35}
      width={300}
    >
      {({ index, style }) => <div style={style}>Item {index}</div>}
    </List>
    ```
    
    ***iv) Avoid Reconciliation and Re-renders***  
    Use keys correctly in lists.
    
    Split large components into smaller ones.
    
    Avoid inline functions/objects as props unless memoized.  
    ***v) Bundle Optimization***  
    Use tools like **Webpack**, **Vite**, or **Parcel** to minimize bundles.
    
    Enable **compression** (gzip, Brotli).
    
    Analyze bundle size with tools like **source-map-explorer** or **webpack-bundle-analyzer**.  
    ***vi) Efficient State Management***  
    Avoid deep prop drilling—use **Context API** or state libraries (Redux, Zustand).
    
    Use **React Query**, **SWR**, or **Apollo Client** for efficient server-state management (caching, revalidation, pagination).  
    ***vii) Server-Side Rendering (SSR) / Static Site Generation (SSG)***  
    Use **Next.js** for SSR or SSG to boost SEO and initial load performance.  
    ***viii) Image Optimization***
    
    Use **responsive images**, `srcSet`, and WebP.
    
    Lazy-load images using `loading="lazy"` or a library like `react-lazyload`.  
    ***ix) Use Production Builds***
    
    Always deploy **production builds** with `npm run build`.
    
    It minifies code and removes warnings, dev-only features.
    
4. **<mark>What are Pure Components in React?</mark>**  
    A **Pure Component** in React is a **class component** that automatically implements a **shallow comparison** in its `shouldComponentUpdate()` lifecycle method.
    
    This means a Pure Component will **only re-render if its props or state have changed** in a meaningful (shallow) way.
    
    ```javascript
    import React, { PureComponent } from 'react';
    
    class MyComponent extends PureComponent {
      render() {
        return <div>{this.props.name}</div>;
      }
    }
    ```
    
    React compares: Primitive values by value, Objects/arrays by reference
    
    So if you pass a new object or array even with the same content, it will trigger a re-render.  
    ***When to Use PureComponent***  
    You have **simple props/state** that benefit from shallow comparison.
    
    You want to avoid unnecessary re-renders.
    
    You’re working in **class-based** components.
    
5. **<mark>Explain the concept of a Memoization in React</mark>**  
    **Memoization** in React is a performance optimization technique that **caches the result of expensive function calls** and **prevents unnecessary re-computations or re-renders** when the inputs haven't changed.  
    ***Why Use Memoization?***
    
    React components can re-render frequently. If,
    
    A component does **expensive calculations**, or
    
    Receives **unchanging props**, or
    
    Uses **functions/handlers that are recreated every render**,
    
    Then memoization helps **avoid repeating the same work**.  
    ***i) useMemo – Memoize a Computation***
    
    ```javascript
    const expensiveValue = useMemo(() => {
      return computeExpensiveValue(input);
    }, [input]);
    ```
    
    `computeExpensiveValue` only re-runs if `input` changes.
    
    Useful for **expensive calculations**.  
    ***ii) useCallback – Memoize a Function***
    
    ```javascript
    const handleClick = useCallback(() => {
      console.log('Clicked!');
    }, []);
    ```
    
    Prevents unnecessary re-creations of a function.
    
    Useful when passing callbacks to **child components** that rely on referential equality.
    
    ***iii) React.memo() – Memoize a Component***
    
    ```javascript
    const MyComponent = React.memo(function MyComponent({ name }) {
      return <div>Hello, {name}</div>;
    });
    ```
    
    Prevents re-rendering unless props actually change.
    
    Similar to `PureComponent` but for **functional components**.  
    ***When Not to Use Memoization***  
    For **lightweight calculations**—it adds complexity and memory overhead.
    
    When dependencies change often (the cache is not effective).
    
    When premature optimization makes code harder to read.
    
6. **<mark>Explain React.memo and React.PureComponent?</mark>**  
    Both `React.memo` and `React.PureComponent` are optimization tools in React that help you **prevent unnecessary re-renders** by performing **shallow comparisons** of props.  
    ***i) React.memo (Functional Components)***  
    `React.memo` is a **higher-order component** that memoizes a **functional component**—meaning React will skip rendering if the **props haven't changed**.
    
    ```javascript
    const MyComponent = React.memo((props) => {
      return <div>{props.name}</div>;
    });
    ```
    
    ***ii) React.PureComponent (Class Components)***  
    `React.PureComponent` is a **base class** for **class components** that implements `shouldComponentUpdate()` with a **shallow prop and state comparison**.
    
    ```javascript
    class MyComponent extends React.PureComponent {
      render() {
        return <div>{this.props.name}</div>;
      }
    }
    ```
    
    This avoids unnecessary re-renders if the props and state are the same (shallow comparison).
    
7. **<mark>What is the React Memo Function?</mark>**  
    `React.memo` is a **higher-order component** (HOC) in React that is used to **optimize performance** by **preventing unnecessary re-renders** of **functional components**.  
    When a component receives the same props as before, `React.memo` allows React to **skip re-rendering** that component, thereby improving efficiency.
    
    ```javascript
    const MyComponent = React.memo(function MyComponent(props) {
      return <div>{props.name}</div>;
    });
    ```
    
    ```javascript
    const Child = React.memo(({ name }) => {
      console.log('Child rendered');
      return <p>Hello, {name}!</p>;
    });
    
    function Parent() {
      const [count, setCount] = React.useState(0);
    
      return (
        <div>
          <button onClick={() => setCount(count + 1)}>Increment</button>
          <Child name="React" />
        </div>
      );
    }
    ```
    
    Even when the parent re-renders, `Child` won't re-render unless the `name` prop changes.  
    ***Shallow Comparison***
    
    React does a **shallow comparison** of props,
    
    i) Primitive values (numbers, strings, booleans) are compared by value.
    
    ii) Objects and arrays are compared by reference.
    
    So if you pass a new object every time—even with the same data—it will re-render.  
    ***When Not to Use React.memo***
    
    i) For components that render very fast anyway.
    
    ii) If props change every time (e.g., inline objects/functions).
    
    iii) If the added complexity outweighs the performance gain.  
    ***When to Use It***
    
    i) Component renders frequently with the **same props**.
    
    ii) Component performance impacts overall app.
    
    iii) You're passing **pure, stable props**.
    
8. **<mark>Explain the useMemo hook and its usage?</mark>**  
    `useMemo` is a **React Hook** that allows you to **memoize the result of a computation**, so it **only re-runs when its dependencies change**. It's used to **optimize performance**, especially for **expensive calculations** or to avoid **unnecessary re-computations** during re-renders.  
    i) **Shallow comparison** is used for dependency checking.
    
    ii) **Only optimize when necessary**—overuse adds complexity and may hurt performance.
    
    iii) **Do not use** `useMemo` to replace `useEffect` or as a side effect. It's **purely for caching returned values**.
    
    ```javascript
    const memoizedValue = useMemo(() => {
      return computeExpensiveValue(input);
    }, [input]);
    // computeExpensiveValue: a function that returns the result you want to cache.
    // [input]: the dependency array; if none of these values change, the function is not re-run.
    ```
    
    ***When to Use useMemo***  
    i) Expensive Calculations
    
    ```javascript
    const expensiveResult = useMemo(() => {
      let total = 0;
      for (let i = 0; i < 100000000; i++) {
        total += i;
      }
      return total;
    }, []);
    ```
    
    ii) Derived Data from Props or State
    
    ```javascript
    const filteredItems = useMemo(() => {
      return items.filter(item => item.includes(search));
    }, [items, search]);
    ```
    
    iii) Avoid Re-Rendering Child Components Based on Derived Props
    
    ```javascript
    const config = useMemo(() => ({ theme: 'dark' }), []);
    <ChildComponent config={config} />
    ```
    
9. **<mark>Explain the useCallback hook and its usage?</mark>**  
    The `useCallback` hook in React is used to **memoize a function**, preventing it from being re-created **on every render**, unless its **dependencies change**.
    
    This is useful when you,
    
    Pass **callback functions** to child components,
    
    Want to prevent **unnecessary re-renders** or re-calculations.
    
    ```javascript
    const memoizedCallback = useCallback(() => {
      // function logic
    }, [dependencies]);
    // memoizedCallback: A memoized version of the function.
    // [dependencies]: The function is re-created only if dependencies change.
    ```
    
    i) `useCallback` is for **memoizing functions**.
    
    ii) Prevents **unnecessary re-creation** of functions on each render.
    
    iii) Useful with **React.memo**, or in **event handlers**, or **callbacks** in dependencies.
    
    ***When to Use useCallback***  
    i) Passing Stable Functions to Children (to avoid re-renders)
    
    ```javascript
    const Parent = () => {
      const [count, setCount] = useState(0);
    
      const handleClick = useCallback(() => {
        console.log('Button clicked');
      }, []);
    
      return <Child onClick={handleClick} />;
    };
    
    const Child = React.memo(({ onClick }) => {
      console.log("Child rendered");
      return <button onClick={onClick}>Click Me</button>;
    });
    ```
    
    ii) Event Handlers Inside Components
    
    ```javascript
    const increment = useCallback(() => {
      setCount(c => c + 1);
    }, []);
    ```
    
    Using `useCallback` here prevents this function from being re-created on every render.  
    ***When Not to Use useCallback***
    
    i) If the function is **not passed to child components**.
    
    ii) If the function is **not computationally expensive**.
    
    iii) Overusing it can **increase complexity** and **hurt performance**.
    
10. **<mark>What is the difference between useCallback and useMemo in React?<br></mark>i) Purpose**  
    useCallback - Memoizes a **function**  
    useMemo - Memoizes a **computed value**  
    **ii) Returns**  
    useCallback - A **memoized function**  
    useMemo - A **memoized result/value**  
    **iii) Usage**  
    useCallback - When you need a stable function reference  
    useMemo - When you need to avoid re-calculating values  
    **iv) Example**  
    useCallback - `useCallback(() => doSomething(), [])`  
    useMemo - `useMemo(() => computeValue(), [])`  
    **v) Primary Use Case**  
    useCallback - Prevents unnecessary re-renders in child components when passing functions  
    useMemo - Prevents expensive recalculations on re-render  
    ***Rule of Thumb***
    
    i) Use `useCallback` when you're **passing a function** as a prop and want to **prevent unnecessary re-renders** of memoized children.
    
    ii) Use `useMemo` when you're doing **expensive calculations** or deriving values from state/props.
    
11. **<mark>What is a React Router?</mark>**  
    **React Router** is a **standard routing library for React** that enables you to **create single-page applications (SPAs)** with **navigation** and **URL management** without refreshing the page.
    
    It allows you to:
    
    i) Define **routes** for different components
    
    ii) Handle **dynamic routing**
    
    iii) Use browser history for navigation
    
    iv) Keep the UI in sync with the URL  
    ***Why Use React Router?***
    
    In a SPA, everything is rendered on a **single HTML page**, so you can't rely on traditional page reloads for navigation. React Router:
    
    i) Changes the URL without full page reload
    
    ii) Loads the correct components dynamically
    
    iii) Helps maintain application **state and structure**  
    ***Installation***
    
    ```javascript
    npm install react-router-dom
    ```
    
    Use `react-router-dom` for web apps. Use `react-router-native` for React Native.
    
    ***i) BrowserRouter***  
    Wraps the entire app and enables routing using the browser's history API.
    
    ```javascript
    import { BrowserRouter } from 'react-router-dom';
    
    <BrowserRouter>
      <App />
    </BrowserRouter>
    ```
    
    ***ii) Routes and Route***  
    Defines path-to-component mappings.
    
    ```javascript
    import { Routes, Route } from 'react-router-dom';
    
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
    </Routes>
    ```
    
    ***iii) Link***
    
    Enables navigation without reloading the page.
    
    ```javascript
    import { Link } from 'react-router-dom';
    
    <Link to="/about">Go to About</Link>
    ```
    
    ***iv) useNavigate***
    
    Programmatic navigation in components.
    
    ```javascript
    import { useNavigate } from 'react-router-dom';
    
    const navigate = useNavigate();
    navigate('/dashboard');
    ```
    
    ***v) useParams***  
    To get dynamic route parameters.
    
    ```javascript
    <Route path="/user/:id" element={<User />} />
    
    // In User component
    const { id } = useParams();
    ```
    
    ***Example***
    
    ```javascript
    import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
    
    function App() {
      return (
        <BrowserRouter>
          <nav>
            <Link to="/">Home</Link> | <Link to="/about">About</Link>
          </nav>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/about" element={<About />} />
          </Routes>
        </BrowserRouter>
      );
    }
    ```
    
12. **<mark>What are the Significant Components of React Router?</mark>**  
    ***i) &lt;BrowserRouter&gt;***
    
    Wraps your entire app to enable client-side routing using the HTML5 history API.
    
    Typically used at the root of your application.
    
    ```javascript
    import { BrowserRouter } from 'react-router-dom';
    
    <BrowserRouter>
      <App />
    </BrowserRouter>
    ```
    
    ***ii) &lt;Routes&gt;***  
    Acts as a **container** for all your route definitions.
    
    Replaces the older `<Switch>` component from v5.
    
    ```javascript
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
    </Routes>
    ```
    
    ***iii) &lt;Route&gt;***  
    Defines a **single route**.
    
    Uses `path` to match the URL and `element` to define what to render.
    
    ```javascript
    <Route path="/contact" element={<Contact />} />
    ```
    
    Supports **nested routes** and **dynamic parameters** (`/user/:id`)
    
    ***iv) &lt;Link&gt;***  
    Provides navigation between routes **without reloading the page**.
    
    Similar to an `<a>` tag, but uses React Router’s internal navigation.
    
    ```javascript
    <Link to="/about">About</Link>
    ```
    
    ***v) useNavigate()***  
    A **hook** to programmatically navigate between routes.
    
    ```javascript
    import { useNavigate } from 'react-router-dom';
    
    const navigate = useNavigate();
    navigate('/dashboard');
    ```
    
    ***vi) useParams()***  
    A hook to extract **URL parameters** from the current route.
    
    ```javascript
    <Route path="/user/:id" element={<User />} />
    
    // In User component
    const { id } = useParams();
    ```
    
    ***vii) useLocation()***  
    Returns the current **location object** (URL, pathname, search params, etc.)
    
    ```javascript
    const location = useLocation();
    console.log(location.pathname);
    ```
    
    ***viii) &lt;Navigate&gt;***  
    Used to **redirect** users programmatically within the route configuration.
    
    ```javascript
    <Route path="/login" element={<Navigate to="/dashboard" />} />
    ```
    
13. **<mark>What are the components of React Router?</mark>**  
    In **React Router**, `<Router>` components are the **core providers** that enable routing in different environments. They wrap your application and manage the **location**, **history**, and **navigation context**.
    
    React Router provides **multiple types of** `<Router>` components based on different use cases.  
    ***i) &lt;BrowserRouter&gt;***  
    Uses the **HTML5 History API** (`pushState`, `popState`)
    
    Clean URLs like `/about`, `/dashboard`
    
    Best for **modern web apps** with server-side support for routing
    
    ```javascript
    import { BrowserRouter } from 'react-router-dom';
    
    <BrowserRouter>
      <App />
    </BrowserRouter>
    ```
    
    ***ii) &lt;HashRouter&gt;***  
    Uses the **URL hash (**`#`) to simulate navigation
    
    URLs look like `/#/about`
    
    Useful for **static sites** or environments where the server doesn’t support route handling
    
    ```javascript
    import { HashRouter } from 'react-router-dom';
    
    <HashRouter>
      <App />
    </HashRouter>
    ```
    
    ***iii) &lt;MemoryRouter&gt;***  
    Stores the navigation **history in memory**
    
    Doesn’t interact with the browser’s URL
    
    Ideal for **testing** or **non-browser environments** (like React Native)
    
    ```javascript
    import { MemoryRouter } from 'react-router-dom';
    
    <MemoryRouter>
      <App />
    </MemoryRouter>
    ```
    
    ***iv) &lt;StaticRouter&gt;***  
    Used for **server-side rendering (SSR)**
    
    Does not respond to user interaction
    
    Typically used with frameworks like **Next.js** or **custom SSR setups**
    
    ```javascript
    import { StaticRouter } from 'react-router-dom/server';
    
    <StaticRouter location="/about">
      <App />
    </StaticRouter>
    ```
    
14. **<mark>Explain the Difference Between Link and NavLink in React Router.</mark>**  
    Both `<Link>` and `<NavLink>` are components provided by **React Router** for **navigating between routes without reloading the page**. The main difference lies in **styling and active state handling**.  
    ***Link -***  
    ***i) Purpose***  
    Basic navigation between routes.
    
    Renders an anchor (`<a>`) tag without page reload.  
    ***ii) Usage***
    
    ```javascript
    import { Link } from 'react-router-dom';
    
    <Link to="/about">About</Link>
    ```
    
    ***iii) Features***  
    Simple and lightweight.
    
    No built-in way to detect or style the **active route**.  
    ***NavLink -  
    i) Purpose***  
    Extended version of `<Link>` that allows **styling the active route**.
    
    Ideal for **navigation menus** or **tabs**.  
    ***ii) Usage***
    
    ```javascript
    import { NavLink } from 'react-router-dom';
    
    <NavLink
      to="/about"
      className={({ isActive }) => (isActive ? "active" : "")}
    >
      About
    </NavLink>
    ```
    
    ***iii) Features***  
    `isActive`: Automatically detects if the link matches the current URL.
    
    Allows **conditional styling** (e.g., highlighting the current page/tab).
    
    Supports **exact matching** and nested routes.  
    ***When to Use Which?***  
    Use `<Link>` when you just need to **navigate**.
    
    Use `<NavLink>` when you need to **highlight the active route** (like in a nav bar or sidebar).
    
15. **<mark>How to get query parameters in React Router v4?</mark>**  
    In **React Router v4**, there is no built-in API to directly access **query parameters** (like `?name=John&age=25`). However, you can easily get them using the `location.search` property combined with the `URLSearchParams` Web API.
    
    ```plaintext
    http://localhost:3000/profile?name=John&age=25
    ```
    
    Inside Your Component
    
    ```javascript
    import React from 'react';
    import { withRouter } from 'react-router-dom';
    
    const Profile = ({ location }) => {
      const query = new URLSearchParams(location.search);
    
      const name = query.get('name'); // John
      const age = query.get('age');   // 25
    
      return (
        <div>
          <h2>Profile</h2>
          <p>Name: {name}</p>
          <p>Age: {age}</p>
        </div>
      );
    };
    
    export default withRouter(Profile);
    // location.search gives you the query string: "?name=John&age=25".
    // new URLSearchParams(...) parses it.
    // .get('key') retrieves the value.
    ```
    
    Alternate (Functional Component with Hooks)
    
    If you're using **React Hooks** with **React Router v5** (or v4 + hooks workaround)
    
    ```javascript
    import { useLocation } from 'react-router-dom';
    
    const useQuery = () => new URLSearchParams(useLocation().search);
    
    const Profile = () => {
      const query = useQuery();
      const name = query.get('name');
      const age = query.get('age');
    
      return (
        <>
          <h2>{name}</h2>
          <p>Age: {age}</p>
        </>
      );
    };
    ```
    
    React Router v4 focuses on rendering and routing. Query param handling is done using standard JavaScript (`URLSearchParams`).
    
16. **<mark>How to perform automatic redirect after login?</mark>**  
    To perform an **automatic redirect after login** in a React app (especially using **React Router**), you typically follow this pattern,  
    i) Authenticate the user
    
    ii) Store login state/token
    
    iii) Use `useNavigate()` (v6) or `history.push()` (v4/v5) to redirect  
    ***Example with React Router v6 (Functional Component)***
    
    ```javascript
    import React, { useState } from 'react';
    import { useNavigate } from 'react-router-dom';
    
    const Login = () => {
      const [username, setUsername] = useState('');
      const [password, setPassword] = useState('');
      const navigate = useNavigate();
    
      const handleLogin = (e) => {
        e.preventDefault();
    
        // Example: validate login (replace with real auth logic)
        if (username === 'admin' && password === '123') {
          // ✅ Store auth token or update global state here
    
          // 🚀 Redirect to dashboard
          navigate('/dashboard');
        } else {
          alert('Invalid credentials');
        }
      };
    
      return (
        <form onSubmit={handleLogin}>
          <input
            value={username}
            onChange={(e) => setUsername(e.target.value)}
            placeholder="Username"
          />
          <input
            value={password}
            type="password"
            onChange={(e) => setPassword(e.target.value)}
            placeholder="Password"
          />
          <button type="submit">Login</button>
        </form>
      );
    };
    
    export default Login;
    ```
    
    ***Example with React Router v4/v5 (***`useHistory`***)***
    
    ```javascript
    import { useHistory } from 'react-router-dom';
    
    const Login = () => {
      const history = useHistory();
    
      const handleLogin = () => {
        // After login success
        history.push('/dashboard');
      };
    
      return <button onClick={handleLogin}>Login</button>;
    };
    ```
    
    i) Redirect after login - `navigate('/dashboard')` or `history.push()`  
    ii) Keep previous location - Use `location.state.from`  
    iii) Redirect after login success - Place redirect logic inside `handleLogin()`
    
17. **<mark>What are the Core Principles of Redux?</mark>**  
    Redux is a **predictable state container** for JavaScript apps, most commonly used with React. It is built around **three core principles** that make application state management predictable and maintainable.  
    ***i) Single Source of Truth***  
    "The state of your whole application is stored in an object tree within a single store."  
    The entire app’s state is stored in **one central object** (the Redux store).
    
    This makes it easier to track, debug, and persist state.
    
    ```javascript
    const initialState = {
      user: { name: 'John', loggedIn: true },
      cart: [{ id: 1, name: 'Apple', quantity: 2 }]
    };
    ```
    
    **Benefit -**  
    Simplifies debugging and testing
    
    Enables easy integration with dev tools and logging  
    ***ii) State is Read-Only***  
    "The only way to change the state is to emit an action, an object describing what happened."  
    You **cannot mutate state directly**.
    
    You must **dispatch an action** to describe what should happen.
    
    ```javascript
    store.dispatch({ type: 'ADD_TODO', payload: { text: 'Learn Redux' } });
    ```
    
    **Benefit -**  
    Makes state mutations **traceable** and **predictable**
    
    Improves maintainability in large apps  
    ***iii) Changes are Made with Pure Functions (Reducers)***  
    "To specify how the state tree is transformed by actions, you write pure reducers."  
    **Reducers** are pure functions that: Take current state and action as input and Return new state **without side effects**
    
    ```javascript
    function todosReducer(state = [], action) {
      switch (action.type) {
        case 'ADD_TODO':
          return [...state, { text: action.payload.text }];
        default:
          return state;
      }
    }
    ```
    
    **Benefit -**
    
    Ensures consistency
    
    Makes logic easy to test and reason about
    
18. **<mark>What are the Core Components of Redux?</mark>**  
    Redux is centered around managing and updating application **state** in a predictable way. Its architecture is built on a few **core components** that work together to maintain a consistent data flow.  
    ***i) Store***  
    The central place that holds the entire state of your application.  
    **Key Responsibilities:**
    
    a) Holds the state object
    
    b) Allows access to state via `getState()`
    
    c) Allows state to be updated via `dispatch(action)`
    
    d) Registers listeners with `subscribe()`
    
    ```javascript
    import { createStore } from 'redux';
    const store = createStore(reducer);
    ```
    
    ***ii) Actions***
    
    Plain JavaScript objects that describe what happened.  
    **Key Features:**
    
    a) Must have a `type` field (string)
    
    b) May contain additional payload data
    
    ```javascript
    const action = {
      type: 'ADD_TODO',
      payload: { text: 'Learn Redux' }
    };
    ```
    
    ***iii) Reducers***
    
    Pure functions that take the current state and an action, and return the new state.  
    **Key Rules:**
    
    a) Must be pure (no side effects)
    
    b) Must not mutate the original state
    
    ```javascript
    const todoReducer = (state = [], action) => {
      switch (action.type) {
        case 'ADD_TODO':
          return [...state, { text: action.payload.text }];
        default:
          return state;
      }
    }
    ```
    
    ***iv) Dispatch***
    
    The method used to send actions to the store.
    
    ```javascript
    store.dispatch({ type: 'ADD_TODO', payload: { text: 'Buy milk' } });
    ```
    
    ***v) Subscribers***
    
    Functions that listen for changes in the store.
    
    ```javascript
    store.subscribe(() => {
      console.log('State updated:', store.getState());
    });
    ```
    
19. **<mark>What are the Advantages of Redux Over React?</mark>**  
    While **React** has its own built-in state system (`useState`, `useReducer`, `Context API`), **Redux** offers a more powerful and structured approach, especially for **complex applications**. Here's a breakdown of how Redux enhances state management compared to vanilla React,  
    ***i) Centralized Global State (Single Source of Truth)***  
    **React Only**:  
    State is often scattered across multiple components.
    
    **Redux**:  
    All application state is stored in a **central store**, making it easy to:
    
    a) Access shared data from anywhere
    
    b) Avoid prop drilling (passing props through many layers)  
    ***ii) Predictability of State***  
    **React**:  
    State can be modified in multiple places, leading to unpredictable behavior in large apps.
    
    **Redux**:  
    State changes only via **pure functions (reducers)** and **explicit actions**, making changes:
    
    a) Predictable
    
    b) Easier to debug and trace  
    ***iii) Better Debugging Tools***
    
    **React**:  
    Limited to browser and component-level inspection.
    
    **Redux**:  
    Integrates with **Redux DevTools**, offering,
    
    a) Time-travel debugging
    
    b) State change history
    
    c) Action logging  
    ***iv) Middleware Support***
    
    **React**:  
    Custom logic like logging, async calls, and analytics are manually handled.
    
    **Redux**:  
    Middleware (e.g., **Redux Thunk**, **Redux Saga**) allows:
    
    a) Handling side effects like async API calls
    
    b) Logging
    
    c) Error reporting  
    ***v) Scalability***
    
    **React**:  
    As the app grows, managing and sharing state across components becomes difficult.
    
    **Redux**:  
    With its organized structure (actions → reducers → store), Redux:
    
    a) Scales better in large apps
    
    b) Makes it easier to maintain and test logic  
    ***vi) Easier Testing***
    
    **React**:  
    Testing component logic can be intertwined with state.
    
    **Redux**:  
    Reducers and actions are pure functions, making them easy to:
    
    a) Unit test
    
    b) Mock state transitions  
    ***vii) Consistent Data Flow***
    
    **React**:  
    State updates might trigger re-renders unpredictably across component trees.
    
    **Redux**:  
    Enforces a strict unidirectional data flow:
    
    Action → Reducer → New State → UI update  
    ***When to Use Redux?***
    
    Use Redux if:
    
    a) Your app has **complex state logic**
    
    b) You need to **share state across many components**
    
    c) You want **time-travel debugging**
    
    d) You're building **enterprise-level** or **large-scale apps**
    
    For small apps or local state, React's built-in state + Context may be enough.
    
20. **<mark>What is the purpose of the constants in Redux?</mark>**  
    In Redux, **constants** are typically used to define **action types**. These are string values that describe what kind of action is being performed (e.g., `"ADD_TODO"` or `"FETCH_USER_SUCCESS"`).  
    ***i) Avoid Typos***
    
    Using constants helps avoid mistakes like this,
    
    ```javascript
    dispatch({ type: ADD_TODO }); // typo would cause a reference error instead
    ```
    
    ***ii) Code Reusability and Centralization***
    
    Action types are declared in one file (e.g., `actionTypes.js`) and used throughout the app,
    
    ```javascript
    // actionTypes.js
    export const ADD_TODO = 'ADD_TODO';
    export const DELETE_TODO = 'DELETE_TODO';
    ```
    
    Now both actions and reducers import from the same source, reducing duplication and increasing consistency.  
    ***iii) Maintainability***
    
    Keeping all action types in one place makes your codebase easier to,
    
    a) Audit
    
    b) Refactor
    
    c) Understand
    
    Especially useful in **large-scale applications**.  
    ***iv) Collaboration and Scalability***
    
    In large teams, having constants helps developers:
    
    a) Understand the available actions
    
    b) Reuse existing ones instead of creating duplicates  
    ***v) Integration with Tools***
    
    Redux dev tools, logs, and testing frameworks can benefit from having standard action type strings to hook into or assert against.  
    ***Constants (actionTypes.js)***
    
    ```javascript
    export const INCREMENT = 'INCREMENT';
    export const DECREMENT = 'DECREMENT';
    ```
    
    ***Action Creator (actions.js)***
    
    ```javascript
    import { INCREMENT } from './actionTypes';
    
    export const increment = () => ({
      type: INCREMENT
    });
    ```
    
    ***Reducer (counterReducer.js)***
    
    ```javascript
    import { INCREMENT, DECREMENT } from './actionTypes';
    
    const counterReducer = (state = 0, action) => {
      switch (action.type) {
        case INCREMENT:
          return state + 1;
        case DECREMENT:
          return state - 1;
        default:
          return state;
      }
    };
    ```
    
21. **<mark>What is a store in Redux?</mark>**  
    In Redux, the **store** is the **central and single source of truth** for your application's state. It is an object that holds the entire **state tree** of your app and provides methods to access and update that state in a predictable way.  
    ***Key Responsibilities of the Redux Store***
    
    i) Holds the application state
    
    ii) Allows access to state via `getState()`
    
    iii) Allows state to be updated via `dispatch(action)`
    
    iv) Registers listeners via `subscribe(listener)`
    
    v) Handles state changes through reducers
    
    ```javascript
    import { createStore } from 'redux';
    import rootReducer from './reducers';
    
    const store = createStore(rootReducer);
    ```
    
    \*\*\*Common Store Methods  
    \*\*\*i) getState() - Returns the current state  
    ii) dispatch() - Sends an action to trigger a state change  
    iii) subscribe() - Registers a callback that runs when the state changes  
    iv) replaceReducer() - Replaces the reducer (used mostly for hot-reloading or dynamic modules)
    
    ***How Store Works in Redux Flow***  
    i) A **component dispatches** an action
    
    ii) The **store** sends the action to the **reducer**
    
    iii) The **reducer** returns a new state
    
    iv) The store **updates its internal state**
    
    v) All **subscribed components** are notified and can re-render
    
    ```javascript
    const store = createStore(counterReducer);
    
    store.subscribe(() => {
      console.log('Current State:', store.getState());
    });
    
    store.dispatch({ type: 'INCREMENT' });
    // Output: Current State: 1
    ```
    
    The **Redux store** is essential for managing and synchronizing state in larger or more complex React applications.
    
22. **<mark>What is an action in Redux?</mark>**  
    In **Redux**, an **action** is a **plain JavaScript object** that describes an **event or change** you want to make to the application state.  
    Think of an action as a **messenger** that carries instructions from your app to the Redux store.  
    ***Structure of an Action***  
    An action **must** have a `type` property (a string), and it **can** have additional data (payload),
    
    ```javascript
    {
      type: 'ADD_TODO',
      payload: {
        text: 'Learn Redux'
      }
    }
    ```
    
    ***Action Properties***
    
    i) `type`: A required string constant that tells Redux what kind of action is happening
    
    ii) `payload`: Optional data that helps reducers update the state
    
    ```javascript
    // Action to add a to-do
    const addTodo = {
      type: 'ADD_TODO',
      payload: { text: 'Buy milk' }
    };
    
    // Action to toggle a task
    const toggleTodo = {
      type: 'TOGGLE_TODO',
      payload: { id: 1 }
    };
    ```
    
    ***Dispatching an Action***  
    Actions are sent to the Redux store using the `dispatch()` method
    
    ```javascript
    store.dispatch(addTodo);
    ```
    
    ***How Actions Fit into Redux Flow***
    
    i) A user interaction or event triggers an **action**
    
    ii) The action is **dispatched** to the store
    
    iii) The store **passes the action to reducers**
    
    iv) Reducers process the action and return **new state**
    
    v) The UI **updates** based on the new state
    
    ***Example With Action Creator Function***  
    Instead of hardcoding the action, you often use **action creators,**
    
    ```javascript
    const addTodo = (text) => {
      return {
        type: 'ADD_TODO',
        payload: { text }
      };
    };
    
    store.dispatch(addTodo('Learn Redux'));
    ```
    
    Actions are the **only way** to tell Redux what to do — making your app’s behavior **predictable and traceable**.
    
23. **<mark>What is a reducer in Redux?</mark>**  
    In **Redux**, a **reducer** is a **pure function** that determines how the application **state** changes in response to an **action**.  
    A reducer **takes the current state and an action**, and **returns a new state** — without mutating the original state.  
    ***Reducer Signature***
    
    ```javascript
    (state, action) => newState
    ```
    
    ***Key Characteristics of Reducers***  
    i) Pure function - Always returns the same output for the same inputs, no side effects  
    ii) Immutable - Does **not** modify the existing state, returns a **new** state object  
    iii) Switch-case - Commonly uses a switch on action.type to determine how to update state
    
    ```javascript
    const counterReducer = (state = 0, action) => {
      switch (action.type) {
        case 'INCREMENT':
          return state + 1;
        case 'DECREMENT':
          return state - 1;
        default:
          return state;
      }
    };
    // state = 0 is the initial/default state.
    // When INCREMENT or DECREMENT is dispatched, it returns the updated state.
    // For any unknown action, it returns the current state unchanged.
    ```
    
    ***Example: Todo List Reducer***
    
    ```javascript
    const todosReducer = (state = [], action) => {
      switch (action.type) {
        case 'ADD_TODO':
          return [...state, { id: action.id, text: action.text, completed: false }];
        case 'TOGGLE_TODO':
          return state.map(todo =>
            todo.id === action.id ? { ...todo, completed: !todo.completed } : todo
          );
        default:
          return state;
      }
    };
    ```
    
    \*\*\*Combining Reducers  
    \*\*\*Redux allows you to combine multiple reducers using `combineReducers()`
    
    ```javascript
    import { combineReducers } from 'redux';
    
    const rootReducer = combineReducers({
      counter: counterReducer,
      todos: todosReducer
    });
    ```
    
    Reducers are the **heart of Redux**, defining how every action transforms your app’s state.
    
24. **<mark>Explain the concept of a Middleware in Redux.</mark>**  
    In **Redux**, **middleware** is a function that **extends the store’s capabilities**. It sits **between the dispatching of an action and the moment it reaches the reducer**.  
    Middleware allows you to **intercept**, **log**, **delay**, or **modify** actions before they reach the reducer.  
    ***Why Use Middleware?***  
    Middleware is useful for handling,
    
    i) Asynchronous operations (e.g., API calls)
    
    ii) Logging and debugging
    
    iii) Conditionally dispatching actions
    
    iv) Error handling
    
    v) Analytics tracking  
    ***Redux Flow with Middleware***
    
    ```javascript
    Component → dispatch(action)
                 ↓
             [Middleware]
                 ↓
             Reducer → New State
    ```
    
    ***Logging Middleware***
    
    ```javascript
    const logger = store => next => action => {
      console.log('Dispatching:', action);
      const result = next(action); // pass action to next middleware or reducer
      console.log('Next State:', store.getState());
      return result;
    };
    // store: Redux store instance
    // next: function that passes the action to the next middleware or reducer
    // action: the action being dispatched
    ```
    
    ***Applying Middleware***  
    Use Redux’s `applyMiddleware()` when creating the store
    
    ```javascript
    import { createStore, applyMiddleware } from 'redux';
    
    const store = createStore(
      rootReducer,
      applyMiddleware(logger)
    );
    ```
    
    ***Common Middleware Libraries***  
    i) redux-thunk - Handles async logic like API calls  
    ii) redux-saga - More powerful async middleware using generators  
    iii) redux-logger - Logs actions and state to console  
    iv) redux-promise - Dispatches promises as actions  
    Middleware makes Redux **powerful and flexible**, enabling complex logic while keeping reducers pure and focused.
    
25. **<mark>What are the Ways To Access the Redux Store?</mark>**  
    In a Redux-powered React app, the **Redux store** holds the global state, and there are several ways to **access or interact** with it.  
    ***i) Using*** `useSelector` ***Hook (Modern & Recommended)***  
    A React-Redux hook that lets you **read data** from the store inside functional components.
    
    ```javascript
    import { useSelector } from 'react-redux';
    
    const count = useSelector(state => state.counter);
    ```
    
    a) Easy to use in function components
    
    b) Subscribes to store updates automatically  
    ***ii) Using*** `useDispatch` ***Hook (Modern)***  
    Allows you to **dispatch actions** to the Redux store from a functional component.
    
    ```javascript
    import { useDispatch } from 'react-redux';
    
    const dispatch = useDispatch();
    dispatch({ type: 'INCREMENT' });
    ```
    
    ***iii) Using*** `connect()` ***Function (Legacy/Classic)***  
    A higher-order component (HOC) from `react-redux` to connect **class components** (or functional ones) to the store.
    
    ```javascript
    import { connect } from 'react-redux';
    
    const MyComponent = ({ count, increment }) => (
      <div>
        <p>{count}</p>
        <button onClick={increment}>+</button>
      </div>
    );
    
    const mapStateToProps = state => ({
      count: state.counter
    });
    
    const mapDispatchToProps = dispatch => ({
      increment: () => dispatch({ type: 'INCREMENT' })
    });
    
    export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
    ```
    
    a) Well-suited for class components
    
    b) Still widely used in legacy code bases  
    ***iv) Using*** `store.getState()` ***Directly (Outside React)***  
    You can directly call `getState()` on the store object, typically outside React components (e.g., in middleware or setup scripts).
    
    ```javascript
    const state = store.getState();
    console.log(state);
    ```
    
    ***v) Using*** `Provider` ***to Make Store Accessible***  
    Before accessing the Redux store in React, you **must wrap your app with** `<Provider>` so the store is available to the whole component tree.
    
    ```javascript
    import { Provider } from 'react-redux';
    import store from './store';
    
    <Provider store={store}>
      <App />
    </Provider>
    ```
    
    In modern React (v16.8+), `useSelector` and `useDispatch` are the most concise and efficient ways to access the Redux store in function components.
    
26. **<mark>What is the difference between mapStateToProps() and mapDispatchToProps()?</mark>**  
    In a **React-Redux** application, `mapStateToProps()` and `mapDispatchToProps()` are two key functions used with the `connect()` function to link your React components to the Redux store.  
    ***i) Purpose***  
    mapStateToProps() - Maps state from Redux store to component props  
    mapDispatchToProps() - Maps dispatchable actions to component props  
    ***ii) Input***  
    mapStateToProps() - Takes the entire Redux state as an argument  
    mapDispatchToProps() - Takes the `dispatch` function as an argument  
    ***iii) Output***  
    mapStateToProps() - Returns an object of state data  
    mapDispatchToProps() - Returns an object of functions that dispatch actions  
    ***iv) Used For***  
    mapStateToProps() - Reading data from the store  
    mapDispatchToProps() - Sending data/commands to the store  
    ***v) Usage***  
    mapStateToProps() - Component can access state via props  
    mapDispatchToProps() - Component can trigger actions via props  
    ***Redux State -***
    
    ```javascript
    const initialState = {
      count: 0
    };
    ```
    
    ***ii) Reducer -***
    
    ```javascript
    function counterReducer(state = initialState, action) {
      switch (action.type) {
        case 'INCREMENT':
          return { count: state.count + 1 };
        default:
          return state;
      }
    }
    ```
    
    ***iii) Component with*** `connect`
    
    ```javascript
    import React from 'react';
    import { connect } from 'react-redux';
    
    const Counter = ({ count, increment }) => (
      <div>
        <p>Count: {count}</p>
        <button onClick={increment}>Increment</button>
      </div>
    );
    
    // 🔹 mapStateToProps: map Redux state to props
    const mapStateToProps = state => ({
      count: state.count
    });
    
    // 🔹 mapDispatchToProps: map dispatch to props
    const mapDispatchToProps = dispatch => ({
      increment: () => dispatch({ type: 'INCREMENT' })
    });
    
    export default connect(mapStateToProps, mapDispatchToProps)(Counter);
    ```
    
    i) mapStateToProps - Pulls data **from** the Redux store  
    ii) mapDispatchToProps - Sends actions **to** the Redux store
    
27. **<mark>How is Relay Different From Redux?</mark>**  
    **Relay** and **Redux** are both state management tools, but they serve **very different purposes** and are often used in different contexts.  
    **Relay** is a **GraphQL client** focused on optimizing how data is fetched and updated.
    
    **Redux** is a **state management** library that gives you manual control over how state flows through your app.  
    Use **Relay** when working with GraphQL APIs.  
    Use **Redux** for managing complex local or global app state regardless of backend.  
    ***i) Purpose***  
    Relay - Data-fetching layer for GraphQL  
    Redux - Predictable state management  
    ***ii) Data Source***  
    Relay - Fetches data from a **GraphQL server**  
    Redux - Manages **client-side state**  
    ***iii) Architecture***  
    Relay - Built around **GraphQL and fragments**  
    Redux - Built around **actions, reducers, and store**  
    ***iv) Updates***  
    Relay - Handles **data normalization** and **caching** automatically  
    Redux - Requires manual updates through reducers  
    ***v) Setup Complexity***  
    Relay - Higher (tight integration with GraphQL)  
    Redux - Lower (generic and flexible)  
    ***vi) Reactivity***  
    Relay - Automatic with GraphQL and subscriptions  
    Redux - Manual, unless using tools like Redux-Saga  
    ***vii) Use Case***  
    Relay - Best for apps with **GraphQL APIs**  
    Redux - Best for apps needing **centralized local state**  
    ***viii) Data Fetching***  
    Relay - Built-in and declarative (`useFragment`, etc.)  
    Redux - Needs middleware like `redux-thunk` or `redux-saga` for async  
    ***ix) Learning Curve***  
    Relay - Steeper (GraphQL + Relay concepts)  
    Redux - Moderate (but more intuitive than Relay)
    
28. **<mark>How to structure Redux top level directories?</mark>**  
    Structuring your Redux directories in a scalable and maintainable way is crucial, especially as your application grows. Below is a **recommended directory structure** for organizing your Redux code, along with explanations and variations based on complexity.
    
    ```plaintext
    src/
    ├── app/
    │   ├── store.js          // Redux store configuration
    │   └── rootReducer.js    // Combines all reducers
    │
    ├── features/             // Feature-based folders
    │   ├── auth/
    │   │   ├── authSlice.js  // Contains reducer, actions, selectors
    │   │   ├── authAPI.js    // API calls related to auth
    │   │   └── authSelectors.js
    │   │
    │   ├── todos/
    │   │   ├── todosSlice.js
    │   │   ├── todosAPI.js
    │   │   └── todosSelectors.js
    │
    ├── components/           // UI components
    │
    ├── pages/                // Route-based pages
    │
    └── index.js              // Entry point
    ```
    
    i) `app/`
    
    Central Redux config files
    
    Contains `store.js`, `rootReducer.js`, and optionally `middleware.js`  
    ii) `features/`
    
    Follows the **“ducks” pattern** or **feature-based grouping**
    
    Each feature (e.g., `auth`, `todos`) contains its own slice  
    iii) `components/`
    
    Reusable UI components
    
    Connected or presentational components can live here  
    iv) `pages/`
    
    Route-based components (e.g., `/login`, `/dashboard`)  
    ***Domain-Driven (Group by feature/domain)***
    
    ```plaintext
    features/
      ├── user/
      ├── product/
      ├── cart/
    ```
    
    ***Classic Redux***
    
    ```plaintext
    redux/
      ├── actions/
      ├── reducers/
      ├── types/
    ```
    
29. **<mark>What is the difference between React context and React Redux?</mark>**  
    Both **React Context** and **React Redux** are used to **share state across components** in a React application, but they serve different purposes and excel in different scenarios.  
    ***i) Purpose***  
    React Context - Built-in way to share data between components (e.g. theme, locale)  
    React Redux - External library for managing global app state  
    ***ii) Data Type***  
    React Context - Ideal for static or rarely changing data  
    React Redux - Designed for dynamic, complex, and large-scale state  
    ***iii) Performance***  
    React Context - Less efficient on frequent updates (can cause re-renders)  
    React Redux - Highly optimized for performance with selective re-renders  
    ***iv) Re-render Control***  
    React Context - Limited (value change re-renders all consumers)  
    React Redux - Fine-grained control using `connect`, `useSelector`, memoization  
    ***v) Data Flow***  
    React Context - One-way data flow  
    React Redux - Unidirectional data flow via actions and reducers  
    ***vi) Boilerplate***  
    React Context - Minimal setup  
    React Redux - Requires setup: store, reducers, actions, etc.  
    ***vii) Middleware Support***  
    React Context - No built-in middleware support  
    React Redux - Supports middleware like `redux-thunk`, `redux-saga`  
    ***viii) Dev Tools***  
    React Context - No built-in dev tools  
    React Redux - Comes with powerful Redux DevTools  
    ***ix) Learning Curve***  
    React Context - Simple and built into React  
    React Redux - Steeper curve (Redux concepts + configuration)  
    ***x) Use Case***  
    React Context - Theming, auth status, user preferences  
    React Redux - Complex state (e.g. UI + API data, pagination, caching)  
    ***When to Use What?***  
    i) Light, static global state (e.g. theme, language) - React Context  
    ii) Complex state with many interrelated parts - Redux  
    iii) Frequent state updates affecting large component trees - Redux  
    iv) Sharing config or environment variables - React Conetxt  
    ***React Context***
    
    ```javascript
    // ThemeContext.js
    const ThemeContext = React.createContext('light');
    
    const App = () => (
      <ThemeContext.Provider value="dark">
        <SomeComponent />
      </ThemeContext.Provider>
    );
    ```
    
    ***Redux***
    
    ```javascript
    // Redux example
    dispatch({ type: "ADD_TODO", payload: "Learn Redux" });
    const todos = useSelector(state => state.todos);
    ```
    
30. **<mark>What is redux-saga?</mark>**  
    **Redux-Saga** is a **middleware library** for handling side effects (like asynchronous operations) in a Redux application using **ES6 generators**.
    
    It allows you to write more manageable, testable, and powerful asynchronous flows, such as:
    
    Data fetching, Delays, Accessing browser APIs, Listening for actions and dispatching other actions.  
    ***Why Use Redux-Saga?***
    
    Redux by itself handles synchronous state changes well. But **side effects** like,
    
    i) Fetching data from an API
    
    ii) Delaying actions
    
    iii) Retrying failed requests
    
    are complex to manage using just `redux-thunk`. Redux-Saga offers a cleaner, more scalable alternative using generator functions.  
    ***Saga Function***
    
    ```javascript
    import { call, put, takeEvery } from 'redux-saga/effects';
    import axios from 'axios';
    
    // Worker Saga
    function* fetchUser(action) {
      try {
        const user = yield call(axios.get, `/api/user/${action.payload}`);
        yield put({ type: 'USER_FETCH_SUCCEEDED', user: user.data });
      } catch (e) {
        yield put({ type: 'USER_FETCH_FAILED', message: e.message });
      }
    }
    
    // Watcher Saga
    function* mySaga() {
      yield takeEvery('USER_FETCH_REQUESTED', fetchUser);
    }
    ```
    
    ***Add to Middleware***
    
    ```javascript
    import createSagaMiddleware from 'redux-saga';
    import { configureStore } from '@reduxjs/toolkit';
    import mySaga from './sagas';
    
    const sagaMiddleware = createSagaMiddleware();
    
    const store = configureStore({
      reducer: rootReducer,
      middleware: [sagaMiddleware]
    });
    
    sagaMiddleware.run(mySaga);
    ```
    
    ***Benefits of Redux-Saga***
    
    i) **Clean, declarative syntax**
    
    ii) **Powerful control over flow** (cancel, debounce, throttle, retry)
    
    iii) Easier to **test** due to pure functions
    
    iv) Handles **complex async logic** better than thunks  
    ***Use When,***
    
    i) You have **complex async flows**
    
    ii) Need **advanced side-effect control** (like race conditions, retries, debouncing)
    
    iii) Want **testable async logic**
    
31. **<mark>How to set initial state in Redux?</mark>**  
    Setting the **initial state** in Redux is straightforward and essential—it defines the starting values of your application’s state before any actions are dispatched.  
    ***i) Set Initial State Directly in the Reducer***
    
    ```javascript
    // counterReducer.js
    const initialState = {
      count: 0
    };
    
    function counterReducer(state = initialState, action) {
      switch (action.type) {
        case 'INCREMENT':
          return { ...state, count: state.count + 1 };
        default:
          return state;
      }
    }
    
    export default counterReducer;
    ```
    
    Here, `state = initialState` ensures that if the state is `undefined` (as it is on first run), Redux uses `initialState`.  
    ***ii) Pass Initial State to the Store (optional override)***  
    You can also pass an initial state directly to `createStore` (for legacy Redux) or `configureStore` from Redux Toolkit, though this is more common in testing or SSR.
    
    ```javascript
    import { createStore } from 'redux';
    import rootReducer from './reducers';
    
    const preloadedState = {
      counter: { count: 10 }
    };
    
    const store = createStore(rootReducer, preloadedState);
    ```
    
    ***Best Practices***
    
    i) Define initial state **within each reducer** or slice for modularity.
    
    ii) Use `preloadedState` if:
    
    You need to **hydrate state from localStorage or server**.
    
    You're writing **unit tests** and want to inject custom state.
    
32. **<mark>What are the differences between call() and put() in redux-saga?</mark>**  
    In **redux-saga**, `call()` and `put()` are both **effects**, used to perform side effects in a more declarative and testable way. However, they serve **very different purposes**.  
    ***i) call() – For Calling Functions (like APIs)***  
    To invoke a **function or asynchronous operation**, such as an API call, with the option to **pause and wait for its result**.
    
    ```javascript
    import axios from 'axios';
    
    function* fetchUser(id) {
      const user = yield call(axios.get, `/api/user/${id}`);
      // waits until axios.get resolves
    }
    ```
    
    ***ii) put() – For Dispatching Redux Actions***  
    To dispatch an **action** to the Redux store (similar to `dispatch()` in regular Redux).
    
    ```javascript
    function* fetchUser(id) {
      try {
        const response = yield call(axios.get, `/api/user/${id}`);
        yield put({ type: 'USER_FETCH_SUCCEEDED', payload: response.data });
      } catch (e) {
        yield put({ type: 'USER_FETCH_FAILED', error: e.message });
      }
    }
    ```
    
    ***Example***
    
    ```javascript
    function* fetchUserSaga(action) {
      try {
        // 1. Call API
        const user = yield call(fetchUserApi, action.payload);
    
        // 2. Dispatch success action
        yield put({ type: 'USER_FETCH_SUCCESS', payload: user });
    
      } catch (error) {
        // 3. Dispatch error action
        yield put({ type: 'USER_FETCH_FAILURE', error: error.message });
      }
    }
    ```
    
    call() - "Wait for a function to finish."  
    put() - "Dispatch an action to Redux."
    
33. **<mark>What are Redux selectors and why use them?</mark>**  
    **Redux selectors** are **pure functions** used to **extract specific pieces of state** from the Redux store.
    
    Instead of accessing state directly in your components (`state.someSlice.someValue`), you use a selector like,
    
    ```javascript
    const someValue = useSelector(selectSomeValue);
    ```
    
    ***Why Use Selectors?***  
    i) Abstraction - Encapsulates how state is accessed, so components don’t depend on the exact structure of the state tree.  
    ii) Reusability - One selector function can be reused across multiple components.  
    iii) Performance - Memoized selectors (using `reselect`) avoid unnecessary recalculations and re-renders.  
    iv) Testability - Pure functions that are easy to unit test.  
    v) Maintainability - Easier to change the state shape later, without updating all component logic.  
    ***Define a selector function***
    
    ```javascript
    // features/user/userSelectors.js
    export const selectUser = (state) => state.user;
    export const selectUserName = (state) => state.user.name;
    ```
    
    ***Use it in a component***
    
    ```javascript
    import { useSelector } from 'react-redux';
    import { selectUserName } from './features/user/userSelectors';
    
    const UserProfile = () => {
      const name = useSelector(selectUserName);
      return <h1>Hello, {name}</h1>;
    };
    ```
    
    ***Where to Put Selectors?***  
    Keep selectors in the same directory as the corresponding slice or in a `selectors.js` file per feature,
    
    ```javascript
    features/
    ├── todos/
    │   ├── todosSlice.js
    │   ├── todosAPI.js
    │   └── todosSelectors.js
    ```
    
34. **<mark>What is Concurrent Rendering in React?</mark>**  
    **Concurrent Rendering** is a React feature that enables the **React rendering engine to interrupt, pause, resume, and reuse work** on multiple components — improving responsiveness and user experience.
    
    It allows React to **work on multiple tasks simultaneously** without blocking the main thread, making UIs more responsive, especially during complex or heavy updates.  
    Without concurrent rendering, React follows a **synchronous, blocking model,** It renders the entire component tree from top to bottom — if it’s slow, your UI freezes.  
    With **Concurrent Rendering,** React can **pause mid-render**, let urgent tasks (like a button click) through, and **resume work later** — making apps **feel faster and more responsive**.  
    i) **Concurrent Rendering is opt-in** via certain APIs — you don’t need to "enable" it globally.
    
    ii) It **does not mean multithreading** — React still runs on the main thread.
    
    iii) It’s about **scheduling** and **interruptibility**, not parallel execution.  
    \*\*\*Benefits of Concurrent Rendering  
    \*\*\*i) Interruptible rendering - Pause rendering work to do more important updates first  
    ii) Improved responsiveness - Keeps the app usable even during expensive updates  
    iii) Prioritized updates - Differentiates between urgent and non-urgent tasks  
    iv) Better user experience - Smooth transitions, less freezing, better perceived performance  
    **Real-World Use Cases**
    
    i) Search filters on large lists
    
    ii) Infinite scrolling
    
    iii) Animations during state updates
    
    iv) Lazy loading content with fallback
    
35. **<mark>What is forwardRef function in React?</mark>**  
    The `forwardRef` function in React is used to **pass a ref through a component to one of its child components**, typically a DOM element.
    
    By default, refs **do not get passed down** from a parent to a child component, but `forwardRef` enables this behavior explicitly.  
    Only **function components** can be used with `forwardRef` (not regular arrow functions).
    
    You **cannot use hooks inside the** `forwardRef` call itself—treat it like a regular functional component.  
    ***Why Use forwardRef?***
    
    i) You’re building **reusable components** (like inputs, buttons) and want the parent to access the **DOM node** inside.
    
    ii) You need to **control focus**, **measure size**, or **trigger animations** from a parent component.
    
    ```javascript
    const MyComponent = React.forwardRef((props, ref) => {
      return <input ref={ref} {...props} />;
    });
    // ref: Comes from the parent component
    // props: The usual props
    // forwardRef: Wraps the component and gives access to the ref
    ```
    
    ***Define a Component Using*** `forwardRef`
    
    ```javascript
    import React, { forwardRef } from 'react';
    
    const FancyInput = forwardRef((props, ref) => {
      return <input ref={ref} className="fancy" {...props} />;
    });
    ```
    
    ***Use It in a Parent***
    
    ```javascript
    import React, { useRef } from 'react';
    
    function ParentComponent() {
      const inputRef = useRef();
    
      const focusInput = () => {
        inputRef.current.focus(); // access the DOM node
      };
    
      return (
        <>
          <FancyInput ref={inputRef} />
          <button onClick={focusInput}>Focus Input</button>
        </>
      );
    }
    ```
    
    ***Common Use Cases***
    
    i) Custom input components
    
    ii) UI libraries (e.g. Material UI, Chakra UI)
    
    iii) Handling animations with libraries like Framer Motion
    
    iv) Integrating with non-React libraries that expect DOM access
    
36. **<mark>What is React hydration?</mark>**  
    **React Hydration** is the process by which React **attaches event listeners and reuses** the **existing HTML markup** generated by the server during **Server-Side Rendering (SSR)**.
    
    Hydration ensures that the React app becomes **interactive** on the client **without re-rendering the entire DOM**, which helps improve performance and perceived load time.  
    ***How It Works***
    
    i) **Server renders** the initial HTML (SSR).
    
    ii) The HTML is sent to the **browser**.
    
    iii) **React "hydrates"** the HTML - it Attaches event handlers, Initializes React's internal state, Avoids replacing existing DOM nodes (reuses them)
    
    ```javascript
    // On the client
    import { hydrateRoot } from 'react-dom/client';
    hydrateRoot(document.getElementById('root'), <App />);
    ```
    
    ***Benefits of Hydration***  
    i) Fast first paint - Browser can show static HTML before React takes over  
    ii) Improved performance - Avoids re-generating the DOM — reuses what SSR created  
    iii) Better SEO - Search engines see fully rendered HTML  
    iv) Full interactivity - Event listeners are added once React hydrates the app
    
    ***Considerations***
    
    i) **Mismatch Warnings**: If server and client HTML differ, React will warn or replace parts of the DOM.
    
    ii) **Hydration errors** can happen due to, Using `window`, `document`, or other browser-only APIs during SSR. Non-deterministic rendering (e.g., random values or time-based data on first render).
    
    iii) Use `useEffect()` (not `useLayoutEffect()`) for client-only logic to avoid SSR warnings.
    
37. <mark>What is the difference between try catch block and error boundaries in React?</mark>  
    In React, `try...catch` blocks and **Error Boundaries** are both mechanisms for handling errors, but they are used in different contexts and have different limitations and capabilities.  
    ***i) try...catch Block***  
    ***Use Case***
    
    a) Used to catch **synchronous errors** in JavaScript code.
    
    b) Typically used in **event handlers**, **functions**, or any **imperative logic**.  
    ***Characteristics***
    
    a) Works only for **imperative code** (i.e., code you call directly).
    
    b) Cannot catch errors during **rendering**, in **lifecycle methods**, or in **asynchronous code** unless awaited properly.
    
    ```javascript
    try {
      const data = JSON.parse('invalid json');
    } catch (error) {
      console.error('Caught an error:', error);
    }
    ```
    
    ***ii) Error Boundaries***  
    ***Use Case***
    
    i) Used to catch **rendering errors** in React **component trees**.
    
    ii) Designed for **React components**, especially in the UI rendering lifecycle.  
    ***Characteristics***
    
    i) Catch errors **during rendering**, **in lifecycle methods**, and **in constructors** of **child components**.
    
    ii) Do **not catch**:
    
    Errors in event handlers (you must use `try...catch` there).
    
    Errors in asynchronous code like `setTimeout`, Promises, or `fetch` (unless you handle those in `.catch()`).
    
    ```javascript
    class ErrorBoundary extends React.Component {
      constructor(props) {
        super(props);
        this.state = { hasError: false };
      }
    
      static getDerivedStateFromError(error) {
        return { hasError: true };
      }
    
      componentDidCatch(error, errorInfo) {
        console.error('Error caught by Error Boundary:', error, errorInfo);
      }
    
      render() {
        if (this.state.hasError) {
          return <h2>Something went wrong.</h2>;
        }
    
        return this.props.children;
      }
    }
    
    // Usage
    <ErrorBoundary>
      <MyComponent />
    </ErrorBoundary>
    ```
    
    When to Use What?  
    i) Use `try...catch` for general JS errors in business logic, async code, or event handlers.
    
    ii) Use **Error Boundaries** to protect your React UI from crashing due to bugs in component rendering.
    
38. **<mark>Explain CORS in React?</mark>**  
    CORS (Cross-Origin Resource Sharing) is **not specific to React**, but it often becomes an issue **when building React apps** that interact with a backend API.  
    ***What is CORS***  
    **CORS** is a **security feature implemented by browsers** to **restrict cross-origin HTTP requests** initiated from scripts running in the browser.  
    **CORS is enforced by the browser**, **not by React**.  
    The **backend server** must include the appropriate **CORS headers** in its response to allow the React frontend to access it.
    
    ```javascript
    // Example of Cors headers
    Access-Control-Allow-Origin: http://localhost:3000
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE
    Access-Control-Allow-Headers: Content-Type
    ```
    
    i) **Origin** = protocol + domain + port
    
    ii) A request is **cross-origin** when your React app (usually running on `localhost:3000`) tries to make a request to an API on a different origin, like `http://api.example.com` or even `localhost:5000`.  
    ***Common Scenario***  
    You run a React app locally
    
    ```javascript
    http://localhost:3000
    ```
    
    And try to fetch data from a backend API
    
    ```javascript
    fetch('http://localhost:5000/api/data')
    ```
    
    The browser blocks this request with a **CORS error** unless the server at `localhost:5000` explicitly allows it.  
    ***How to Fix CORS in Development***  
    i) Enable CORS on the Server
    
    ```javascript
    // In Node.js/Express (backend)
    const cors = require('cors');
    app.use(cors({ origin: 'http://localhost:3000' }));
    ```
    
    ii) Use a Proxy in React (for development only)
    
    ```javascript
    // Set up a proxy in package.json
    "proxy": "http://localhost:5000"
    // This tells the development server to proxy API requests to the backend, 
    // avoiding CORS issues.
    fetch('/api/data') 
    // This gets proxied to http://localhost:5000/api/data
    ```
    
39. **<mark>How can we provide the security for any React Application?</mark>**  
    Securing a **React application** involves both **frontend precautions** and strong **backend security**. React is just the **UI layer**, so the real security enforcement happens on the **server**, but you can—and should—harden your React app to avoid common risks.  
    ***How to Secure a React Application***  
    ***i) Protect Against XSS (Cross-Site Scripting)***
    
    ```javascript
    // React is safe by default — it escapes values in JSX
    <p>{userInput}</p> 
    // Safe: React escapes it
    
    // Avoid dangerouslySetInnerHTML unless absolutely necessary
    <div dangerouslySetInnerHTML={{ __html: untrustedHTML }} /> // ⚠️ Risky
    
    // Sanitize data if you must use raw HTML (use libraries like DOMPurify)
    ```
    
    ***ii) Use HTTPS***  
    Always serve your app over HTTPS, especially in production.
    
    Enforce HTTPS using server configurations or redirects.  
    ***iii) Handle Authentication Securely***
    
    Use **JWT (JSON Web Tokens)**, **OAuth**, or **session-based auth**.
    
    Store tokens securely:
    
    **Best Practice**: Use **HTTP-only cookies** (more secure than localStorage).
    
    Avoid storing JWTs in `localStorage` or `sessionStorage` if you can (they're vulnerable to XSS).  
    ***iv) Implement Role-Based Access Control (RBAC)***  
    On the frontend, **hide UI elements** based on user roles.
    
    On the backend, **enforce permissions** — never trust the frontend to control access.
    
    ```javascript
    {user.role === 'admin' && <AdminPanel />}
    ```
    
    ***v) Avoid Exposing Sensitive Data in the Frontend***
    
    Never include secrets, API keys, or passwords in your React code.
    
    Even `env` variables in `.env` files (like `REACT_APP_SECRET`) are exposed in the client bundle!  
    ***vi) Secure Your API***
    
    Use CORS to **restrict who can access your backend**.
    
    Validate and sanitize all inputs server-side.
    
    Rate-limit and throttle requests to prevent abuse (e.g., with libraries like `express-rate-limit`).  
    ***vii) Use Dependency Audits and Updates***
    
    Keep dependencies up to date.
    
    Use tools like:
    
    `npm audit`
    
    `yarn audit`
    
    GitHub Dependabot  
    ***viii) Enable Code Splitting and Lazy Loading***
    
    Reduces attack surface by loading only what’s needed.
    
    Use React's `React.lazy()` and `Suspense` to defer loading code.  
    ***ix) Security Headers (via Backend)***  
    If serving React from Node/Express
    
    ```javascript
    npm install helmet
    ```
    
    ```javascript
    const helmet = require('helmet');
    app.use(helmet());
    ```
    
40. **<mark>How can we improve the performance of the React Application?</mark>**  
    Improving the **performance of a React application** is essential for ensuring fast load times, smooth interactions, and a better user experience. Here’s a comprehensive guide to performance optimization in React,  
    ***i) Use React’s Production Build***  
    Use the optimized production version by running,
    
    ```javascript
    npm run build
    ```
    
    this minifies code
    
    it removes development warnings
    
    it also enables performance optimizations  
    ***ii) Code Splitting with*** `React.lazy()` ***and*** `Suspense`
    
    Split code and load components **only when needed**
    
    ```javascript
    const AdminPanel = React.lazy(() => import('./AdminPanel'));
    
    <Suspense fallback={<Spinner />}>
      <AdminPanel />
    </Suspense>
    ```
    
    Reduces initial bundle size and improves load speed.  
    ***iii) Memoization Techniques***  
    React.memo() - Prevent re-rendering of functional components unless props change
    
    ```javascript
    const MyComponent = React.memo(({ data }) => { ... });
    ```
    
    `useMemo()` and `useCallback()` -  
    `useMemo` caches expensive calculations  
    `useCallback` caches functions to avoid unnecessary renders
    
    ```javascript
    const filteredList = useMemo(() => filterData(data), [data]);
    const handleClick = useCallback(() => doSomething(id), [id]);
    ```
    
    ***iv) Avoid Unnecessary Re-renders***  
    Structure components well and avoid prop drilling.
    
    Use tools like **React DevTools** to identify re-renders.
    
    Lift state up only when necessary.  
    ***v) Virtualize Long Lists***  
    Use libraries like `react-window` or `react-virtualized`
    
    ```javascript
    import { FixedSizeList as List } from 'react-window';
    
    <List height={500} itemCount={1000} itemSize={35}>
      {({ index, style }) => <div style={style}>Item {index}</div>}
    </List>
    ```
    
    Renders only visible items for large lists — massive performance gain.  
    ***vi) Debounce Input Handlers***  
    For expensive actions like API calls on input change,
    
    ```javascript
    const debouncedSearch = useMemo(() => debounce(searchFunc, 300), []);
    ```
    
    Use `lodash.debounce` or a custom debounce function.  
    ***vii) Use Efficient Images and Assets***  
    Compress and optimize images.
    
    Use `WebP` or `AVIF` formats.
    
    Use `lazy loading` for images
    
    ```javascript
    <img src="image.jpg" loading="lazy" alt="example" />
    ```
    
41. **<mark>How do you handle performance optimization in a React application?</mark>**  
    Handling **performance optimization in a React application** means making the UI faster, more responsive, and efficient by reducing unnecessary work and improving the way your app loads and updates components. Here's how I would handle it systematically,  
    ***i) Build with Production Optimizations***  
    I always ensure the app is built with `npm run build` for production. This: Minifies code, Removes development warnings, Optimizes React for performance  
    ***ii) Code Splitting & Lazy Loading***
    
    I use `React.lazy()` and `Suspense` to split code and defer loading components until they are needed
    
    ```javascript
    const Dashboard = React.lazy(() => import('./Dashboard'));
    ```
    
    Reduces initial load time by loading parts of the app on demand.  
    ***iii) Prevent Unnecessary Re-renders***  
    `React.memo()` for pure components
    
    `useCallback()` for functions passed as props
    
    `useMemo()` for expensive calculations
    
    ```javascript
    const filteredData = useMemo(() => expensiveFilter(data), [data]);
    ```
    
    Keeps components from re-rendering unless they really need to.  
    ***iv) Optimize State Management***  
    I avoid "lifting state up" unnecessarily and scope state locally when possible. For global state, I:
    
    Prefer `useReducer` for complex state logic
    
    Use optimized state libraries like **Zustand** or **Jotai** over bulky ones when possible  
    ***v) Virtualize Large Lists***  
    When dealing with large datasets, I use `react-window` or `react-virtualized`
    
    ```javascript
    <FixedSizeList itemCount={1000} itemSize={35} height={500} width={300}>
      {({ index, style }) => <div style={style}>Row {index}</div>}
    </FixedSizeList>
    ```
    
    Prevents DOM bloat by only rendering visible items.  
    ***vi) Debounce Expensive Input Handling***
    
    To avoid laggy UIs during typing/searching, I debounce handlers
    
    ```javascript
    const debouncedSearch = useMemo(() => debounce(handleSearch, 300), []);
    ```
    
    Smoothens interactions and avoids unnecessary re-renders or API calls.  
    ***vii) Optimize Images & Assets***
    
    Use compressed images in `WebP` format.
    
    Lazy-load images with the `loading="lazy"` attribute.
    
    Use SVGs for simple icons/logos.  
    ***viii) Minimize Bundle Size***
    
    I analyze the bundle with `source-map-explorer` or `webpack-bundle-analyzer`.
    
    Use only needed parts of libraries (e.g., `import debounce from 'lodash/debounce'`).
    
    Avoid heavy libraries when a smaller utility will do.  
    ***ix) Use Browser Caching and Service Workers***
    
    For progressive apps,
    
    I set up service workers with tools like `Workbox`.
    
    Cache static assets, fonts, and API responses.  
    ***x) Monitor and Audit Performance***
    
    I regularly use,
    
    **React DevTools** to inspect component renders.
    
    **Chrome Lighthouse** for performance scores.
    
    **Web Vitals** to measure real user metrics.
    
42. **<mark>How to check the performance of React app using LightHouse?</mark>**
    
    To check the **performance of a React app using Lighthouse**, you can use **Google Chrome DevTools**, which includes Lighthouse as a built-in feature.  
    ***i) Open Your React App in Chrome***  
    Make sure it's running either locally (e.g., `http://localhost:3000`) or deployed online.  
    ***ii) Open Chrome DevTools***
    
    Right-click anywhere on the page → click **Inspect**, or
    
    Press `Ctrl + Shift + I` (Windows/Linux) or `Cmd + Option + I` (Mac)  
    ***iii) Go to the "Lighthouse" Tab***
    
    In DevTools, click the **"Lighthouse"** tab.
    
    If you don’t see it, click the `»` icon to find it in the overflow menu.  
    ***iv) Select Audit Categories***  
    Usually, for React apps, you’ll want at least:
    
    Performance, Best Practices, Accessibility  
    ***v) Choose Device Type***
    
    Choose **Mobile** (default) or **Desktop**
    
    Mobile emulation simulates a slower device/network — good for real-world performance insights.  
    ***vi) Run the Audit***
    
    Click **"Analyze page load"** or **"Generate report"**.
    
    Lighthouse will reload your page, run a series of tests, and then show a detailed report.
    
43. **<mark>How to enable production mode in React?</mark>**  
    To **enable production mode in React**, you need to **build your app using the production configuration** provided by your build tool (e.g., Create React App, Vite, Webpack, etc.).  
    ***i) Using Create React App (CRA)***
    
    ```javascript
    npm run build
    # or
    yarn build
    ```
    
    This does the following:
    
    Sets `process.env.NODE_ENV` to `'production'`
    
    Minifies and optimizes your code
    
    Removes React development warnings and logs
    
    The production-ready files will be output to the `build/` directory.  
    To serve the production build locally,
    
    ```javascript
    npm install -g serve
    serve -s build
    ```
    
    ***ii) Using Vite***  
    Run the production build command,
    
    ```javascript
    npm run build
    ```
    
    This creates an optimized build in the `dist/` folder.
    
    To preview it
    
    ```javascript
    npm run preview
    ```
    
    iii) Using Webpack (Custom Setup)  
    In your Webpack config,
    
    ```javascript
    mode: 'production'
    ```
    
    Then run your custom production build,
    
    ```javascript
    webpack --mode production
    ```
    
    ***Why Production Mode Matters***  
    **i) Warnings & Debug Info**  
    Development Mode - Enabled  
    Production Mode - Disabled  
    **ii) Performance**  
    Development Mode - Slower  
    Production Mode - Optimized  
    **iii) Bundle Size**  
    Development Mode - Larger  
    Production Mode - Minified & Tree-shaken  
    **iv) Environment Variable**  
    Development Mode - NODE\_ENV=development  
    Production Mode - NODE\_ENV=production
    
44. **<mark>Whar are the efficient way to deply your React Application?</mark>**  
    Deploying a React application efficiently depends on your project’s complexity, scalability requirements, and your team's familiarity with deployment tools. Here are some efficient and popular ways to deploy a React app,  
    ***i) Vercel (Recommended for Simplicity and Performance)***  
    **Pros**
    
    a) Automatic deployments from GitHub/GitLab/Bitbucket
    
    b) Built-in CDN for fast loading
    
    c) Serverless functions supported
    
    d) Great DX (developer experience)
    
    **Usage**
    
    a) Push code to a Git repository
    
    b) Connect the repo to Vercel
    
    c) Vercel auto-builds and deploys on push  
    ***ii) Netlify***
    
    **Pros**
    
    a) Similar to Vercel with automatic Git-based deployments
    
    b) Supports serverless functions and forms
    
    c) Custom domain and HTTPS setup with ease
    
    **Usage**
    
    a) Connect your repo
    
    b) Configure build command (`npm run build`)
    
    c) Set publish directory to `build/`  
    ***iii) GitHub Pages***
    
    **Pros**
    
    a) Free and simple for static sites
    
    **Cons**
    
    a) Only works for static builds
    
    **Usage**
    
    a) Build the app: `npm run build`
    
    b) Use the `gh-pages` package to push the `build/` folder
    
    c) Add `"homepage": "https://<username>.github.io/<repo>"` to `package.json`  
    ***iv) Firebase Hosting***
    
    **Pros**
    
    a) Fast CDN, custom domains, and HTTPS
    
    b) Good for apps that may use Firebase backend services
    
    **Usage**
    
    a) Install Firebase CLI: `npm install -g firebase-tools`
    
    b) Initialize: `firebase init`
    
    c) Deploy: `firebase deploy`  
    ***v) AWS Amplify***
    
    **Pros**
    
    a) Powerful for full-stack apps
    
    b) Git-based CI/CD, serverless backend
    
    **Cons**
    
    a) Slightly steeper learning curve
    
    **Usage**
    
    a) Connect Git repository
    
    b) Amplify handles build and deployment
    
    c) Optional: Use CLI for advanced customization  
    ***vi) Docker + NGINX (Advanced/Production)***
    
    **Pros**
    
    a) Fully customizable and secure
    
    b) Great for enterprise or containerized environments
    
    **Cons**
    
    a) Requires infrastructure knowledge
    
    **Usage**
    
    a) Dockerize your React app with NGINX to serve the static files
    
    b) Deploy to any cloud provider (AWS EC2, DigitalOcean, etc.)  
    ***Tips for Efficient Deployment***
    
    i) **Use a CDN** to cache and serve static assets faster
    
    ii) **Enable gzip or Brotli compression** for minimized file sizes
    
    iii) **Lazy load components** to reduce initial bundle size
    
    iv) **Monitor performance** using tools like Lighthouse or Web Vitals
    
    v) **Automate deployment** using Git hooks or CI/CD (GitHub Actions, GitLab CI)
    
45. **<mark>What is the latest stable version of React and What is new in it?</mark>**  
    As of May 2025, the latest stable version of React is **React 19.1.0**, released on March 28, 2025. This version builds upon the major release of React 19.0.0, which became stable on December 5, 2024.  
    React 19 introduces several significant features and improvements aimed at enhancing developer experience, performance, and code maintainability.  
    ***i) React Compiler***
    
    A new compiler that automatically optimizes your code, eliminating the need for manual memoization with `useMemo`, `useCallback`, or `memo`. This leads to cleaner code and improved performance.  
    ***ii) Server Components***
    
    Enables rendering parts of your UI on the server, reducing client-side JavaScript and improving performance and SEO.  
    ***iii) New Hooks***
    
    `useActionState`: Manages state transitions in asynchronous actions.
    
    `useFormStatus`: Provides status information for form submissions.
    
    `useOptimistic`: Allows optimistic UI updates, enhancing user experience during async operations.  
    ***iv) use() API***
    
    A new hook that simplifies data fetching by allowing you to await promises directly within components, reducing boilerplate code.  
    ***v) Actions API***
    
    Simplifies asynchronous state updates by integrating async functions directly into React's rendering cycle, reducing the need for complex state management logic.  
    ***vi) Enhanced Concurrent Rendering***
    
    Improvements to React's concurrent rendering capabilities, including better scheduling and automatic batching of state updates, leading to more responsive applications.  
    ***vii) Simplified Ref Handling***
    
    You can now pass refs as regular props, making it easier to work with custom components and reducing the need for `forwardRef`.  
    ***viii) Native Metadata Rendering***
    
    Support for rendering document metadata (`<title>`, `<meta>`, `<link>`) directly within React components, enhancing SEO and simplifying head management.  
    ***How to Upgrade***  
    To upgrade to React 19.1.0, run,
    
    ```javascript
    npm install react@19.1.0 react-dom@19.1.0
    ```
    
    Before upgrading, it's recommended to update to React 18.3.1 to identify any deprecated APIs and prepare your codebase for the transition.
    
46. **<mark>How to Update ReactJS to the Latest Version?</mark>**  
    Updating **ReactJS to the latest version** involves a few steps to ensure compatibility and stability. Here's a clear, step-by-step guide,  
    ***i) Check Current Version***
    
    ```javascript
    npm list react
    npm list react-dom
    ```
    
    ***ii) Review React Release Notes***
    
    Visit the official React blog or GitHub releases to,
    
    Understand breaking changes
    
    Find deprecated APIs
    
    Read migration instructions
    
    ***iii) Update Dependencies***
    
    To update to the latest **stable version** (e.g., React 19.1.0 as of May 2025)
    
    ```javascript
    npm install react@latest react-dom@latest
    ```
    
    Or with Yarn
    
    ```javascript
    yarn add react@latest react-dom@latest
    ```
    
    ***iv) Update Related Packages***
    
    Update any other related packages you might be using
    
    ```javascript
    npm install react-scripts@latest       # If using CRA
    npm install @types/react @types/react-dom  # If using TypeScript
    ```
    
    Also update testing libraries if needed
    
    ```javascript
    npm install @testing-library/react @testing-library/jest-dom
    ```
    
    ***v) Update browserslist***
    
    Modern React may rely on updated browser features:  
    In `package.json`, update
    
    ```javascript
    "browserslist": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
    ```
    
    ***vi) Check and Fix Breaking Changes***
    
    If moving between major versions (e.g., 18 → 19):
    
    Search for deprecated APIs you use (e.g., `ReactDOM.render` → `createRoot`)
    
    Use the React 19 Migration Guide  
    ***vii) Test Thoroughly***
    
    ```javascript
    npm run build
    npm test
    npm start
    ```
    
47. **<mark>How to handle Security Vulnerabilities in React Application?</mark>**  
    Handling **security vulnerabilities** in a React application requires a mix of best practices, tooling, and awareness of common threats. Here's a comprehensive guide to secure your React app effectively,  
    ***i) Prevent Cross-Site Scripting (XSS)***  
    **a) React Auto-Escapes**
    
    React automatically escapes values in JSX,
    
    ```javascript
    <div>{userInput}</div> // Safe
    ```
    
    **b) Avoid dangerouslySetInnerHTML**
    
    Only use when absolutely necessary, and sanitize the input
    
    ```javascript
    <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userContent) }} />
    ```
    
    ***ii) Avoid Insecure Dependencies***  
    Audit and Patch - Regularly run following comands
    
    ```javascript
    npm audit fix
    npm audit
    ```
    
    ***iii) Secure API Communication***  
    **a) Use HTTPS for all requests**
    
    Enforce HTTPS via your backend or proxy
    
    **b) Validate and Sanitize Input on the Server**
    
    Even if React validates input, backend must never trust client data
    
    **c) Use Authentication and Authorization**
    
    Implement proper token-based auth (e.g., JWT, OAuth)
    
    Avoid storing sensitive tokens in `localStorage`; use `HttpOnly` cookies if possible  
    ***iv) Set Proper Content Security Policy (CSP)***  
    Prevent inline scripts and external attacks,
    
    ```javascript
    Content-Security-Policy: default-src 'self'; script-src 'self';
    ```
    
    Use tools like **Helmet** (for Express apps),
    
    ```javascript
    npm install helmet
    ```
    
    ```javascript
    app.use(require("helmet")());
    ```
    
    ***v) Prevent Cross-Site Request Forgery (CSRF)***  
    If using cookies for auth, implement CSRF tokens
    
    Use libraries like `csurf` (Node/Express)
    
    Use **SameSite** and **HttpOnly** cookie flags  
    ***vi) Avoid Leaking Sensitive Data***  
    Never commit: API keys, Environment files (`.env`), Secrets in public GitHub repos  
    ***vii) Keep React and Dependencies Updated***
    
    a) Use latest versions of React, React DOM, and other packages
    
    b) Monitor official changelogs for security patches  
    ***viii) Limit Exposure of Build Info***
    
    a) Avoid exposing: Build metadata, Version numbers, Stack traces
    
    b) Set `NODE_ENV=production` and configure error boundaries.  
    ***ix) Use Error Boundaries***  
    Prevent exposing internal logic to users
    
48. **<mark>Explain the Webpack in React and Nodejs</mark>**  
    **Webpack** is a powerful module bundler used in modern JavaScript applications, especially in projects using **React** and sometimes with **Node.js** (mainly for frontend assets).  
    ***What Is Webpack?***
    
    Webpack takes all your project files—JavaScript, CSS, images, etc.—and **bundles** them into one or more optimized files for the browser.  
    ***Core Concepts of Webpack***
    
    i) **Entry:** Where Webpack starts bundling.
    
    ```javascript
    entry: './src/index.js'
    ```
    
    ii) **Output**: Where Webpack saves the bundled files.
    
    ```javascript
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'bundle.js'
    }
    ```
    
    iii) **Loaders**: Transform non-JS files (like JSX, CSS, images) into valid modules.
    
    `babel-loader` (transpile JSX/ES6)
    
    `css-loader`, `style-loader` (handle CSS)
    
    `file-loader`, `url-loader` (handle assets)  
    iv) **Plugins**: Perform tasks like optimizing bundles, generating HTML, cleaning the output directory.
    
    `HtmlWebpackPlugin`
    
    `CleanWebpackPlugin`
    
    `MiniCssExtractPlugin`  
    v) **Mode**: Either `development` or `production`
    
    ```javascript
    mode: 'development'  // or 'production'
    ```
    
    ***Webpack in React***  
    **i) Why It’s Used**
    
    a) Bundle JSX and modern JavaScript
    
    b) Enable hot module reloading
    
    c) Optimize performance (tree shaking, code splitting)
    
    ```javascript
    // webpack.config.js
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      entry: './src/index.jsx',
      output: {
        filename: 'bundle.js',
        path: __dirname + '/dist',
      },
      module: {
        rules: [
          {
            test: /\.(js|jsx)$/,
            use: 'babel-loader',
            exclude: /node_modules/,
          },
          {
            test: /\.css$/,
            use: ['style-loader', 'css-loader'],
          }
        ]
      },
      plugins: [
        new HtmlWebpackPlugin({ template: './public/index.html' })
      ],
      resolve: {
        extensions: ['.js', '.jsx'],
      },
      devServer: {
        static: './dist',
        hot: true,
      }
    };
    ```
    
    ***Webpack in Node.js***  
    Webpack isn’t typically used to **bundle backend Node.js code** (since Node understands modules), but it **can be used** for:
    
    a) **Bundling frontend assets** in a full-stack app
    
    b) **Serverless deployments** or SSR setups
    
    c) Using **Webpack for Lambda Functions** (e.g., with AWS)  
    **Use Case Example**
    
    A Node.js + Express server with Webpack to serve a React frontend:
    
    a) React app → Bundled by Webpack
    
    b) Served by Express from `/dist`
