Study material

Reactjs

Attachments(1)

Quiz
Quiz

Core Concepts and Architecture

The foundation of React involves understanding how it interacts with the Document Object Model (DOM), handles component rendering, and maintains structural integrity during development.

The Virtual DOM

The Virtual DOM is a lightweight, in-memory representation of the actual HTML DOM. React uses this abstraction to optimize rendering performance. Instead of updating the real DOM immediately when state changes, React updates the Virtual DOM first. It then compares the new Virtual DOM with a snapshot of the previous one (a process called reconciliation or diffing). Finally, it calculates the most efficient way to update the real DOM and applies only those specific changes.

A common misconception is that the Virtual DOM directly updates the real DOM faster. In reality, real DOM manipulation is always slow. The Virtual DOM is faster because it minimizes direct manipulations by batching updates and applying them simultaneously.

By default, standard tree edit distance algorithms operate in O(n3)O(n^3) time complexity. React implements a heuristic O(n)O(n) algorithm based on assumptions about element types and keys.

React Fragments and Strict Mode

  • React.Fragment: Returning multiple sibling elements from a component normally requires wrapping them in a parent element (like a <div>). This can pollute the DOM tree and break CSS grid or flexbox layouts. Fragments (<React.Fragment> or the shorthand <></>) allow returning multiple elements without adding extraneous nodes to the DOM.
  • React Strict Mode: A development-only wrapper (<React.StrictMode>) that intentionally renders components twice. This duplicate rendering helps identify side effects, deprecated lifecycle methods, and unsafe state mutations that might cause bugs in production.

Summary: The Virtual DOM optimizes updates via batching, Fragments keep the DOM tree clean, and Strict Mode enforces pure functions in development.

Self-Check: Why does Strict Mode render components twice, and does this affect the production build?


Components, Props, and Data Flow

React applications are built from isolated pieces of UI called components, which pass data downward using properties.

Immutability of Props

Props (properties) are the mechanism for passing data from parent to child components. A strict rule in React is that a component must never modify its own props. Components must act as pure functions with respect to their props. If a component needs to alter data based on a prop, it must do so by managing its own local state or by invoking a callback function passed down from the parent.

Prop Drilling

Prop Drilling is the process of passing props through multiple intermediate nested components that do not need the data themselves, purely to reach a deeply nested child component that does.

Note: Context API or state management libraries are typically used to resolve severe prop drilling.

Conditional Rendering and HTML Injection

  • Conditional Rendering: React relies on standard JavaScript operators to render UI conditionally inline. The recommended approaches are the ternary operator (condition ? <ComponentA/> : <ComponentB/>) and the logical AND operator (condition && <Component/>).
  • HTML Injection: Injecting raw HTML strings directly into the DOM is handled via the dangerouslySetInnerHTML attribute. The verbose and intimidating name acts as a semantic warning that this practice exposes the application to Cross-Site Scripting (XSS) attacks.

Summary: Data flows top-down via immutable props, inline conditional logic dictates rendering, and direct HTML injection is explicitly flagged as hazardous.

Self-Check: How does the ternary operator differ structurally from the logical AND operator in JSX rendering?


State Management and Forms

State dictates the interactive portions of a React application. Handling user input requires bridging standard HTML behavior with React's state management.

Controlled Components

In a standard HTML form, elements like <input>, <textarea>, and <select> maintain their own internal state. In a Controlled Component, the form data is exclusively controlled by the React state. The component dictates the value of the input, and state updates occur via an onChange handler.

// Worked Example: Controlled Component
const NameForm = () => {
  const [name, setName] = useState("");

  const handleChange = (event) => {
    setName(event.target.value); // State dictates input value
  };

  return <input type="text" value={name} onChange={handleChange} />;
};

Asynchronous State Updates

When a state setter function (e.g., from useState) is invoked, the state does not update immediately on the next line of code. React groups (batches) multiple state updates together into a single render pass to optimize performance and prevent unnecessary re-renders.

Developers often attempt to console.log() a state variable immediately after calling its setter function and become confused when the old value is printed. The state value is only guaranteed to be updated on the next render cycle.

Summary: Controlled components synchronize form inputs with React state, while state updates are batched asynchronously for optimal performance.

Self-Check: If a state setter is called three times synchronously in the same function, how many re-renders will React trigger?


React Hooks

Hooks allow functional components to "hook into" React state and lifecycle features.

Rules of Hooks

To ensure predictability, React enforces strict rules:

  1. Top Level Only: Hooks must be called at the top level of the component. They cannot be placed inside loops, conditions, or nested functions. This guarantees that Hooks are executed in the exact same order every time a component renders.
  2. React Functions Only: Hooks can only be called from functional React components or custom hooks, never from standard JavaScript functions or class components.

The useEffect Hook

The useEffect hook manages side effects (data fetching, subscriptions, manual DOM manipulation). It accepts two arguments: a setup function and an optional dependency array.

Dependency Array StatusExecution Behavior
Omitted completelyEffect runs after the initial mount and after every single re-render.
**Empty array []**Effect runs only once after the initial mount.
**Array with values [x, y]**Effect runs after initial mount and whenever x or y change.

Cleanup Phase: If the effect returns a function, React treats this as a cleanup mechanism. This returned function mimics componentWillUnmount. It executes immediately before the component unmounts, or before the effect re-runs due to a dependency change.

The useRef Hook

While often used to directly reference DOM elements, useRef is fundamentally used to store a mutable value that does not trigger a re-render when updated. It returns an object with a single property: .current. Modifying .current happens synchronously and silently, making it ideal for storing interval IDs, previous state values, or rendering flags.

Summary: Hooks must execute in a consistent order at the top level; useEffect handles side effects and cleanups based on dependency arrays, while useRef holds mutable data without triggering renders.

Self-Check: Why does placing a hook inside an if statement violate React's internal tracking mechanism?


Performance Optimization

As applications grow, preventing unnecessary calculation and rendering becomes critical.

useMemo vs useCallback

Both hooks prevent unnecessary work during re-renders, but they memoize different things:

  • useMemo: Memoizes a computed value. It executes a provided function and caches the result. It only recalculates the value when its dependencies change. Used for computationally expensive operations (e.g., sorting large arrays).
  • useCallback: Memoizes a function definition. It caches the function instance itself so that the exact same function reference is passed across renders. Used primarily when passing callbacks as props to optimized child components.

Mnemonic: useMemo returns the Menu (the final product/value). useCallback returns the Cook (the function itself).

React.memo

While hooks optimize internal logic, React.memo optimizes component rendering. It is a Higher-Order Component (HOC) that wraps a functional component. It memoizes the entire component, skipping re-renders if the incoming props remain strictly identical to the previous render.

Summary: useMemo caches values, useCallback caches functions, and React.memo caches entire component renders based on prop equality.

Self-Check: If a parent component creates a new object inline and passes it as a prop to a child wrapped in React.memo, will the child re-render?


Advanced Patterns and Ecosystem

Handling edge cases, global data, and large bundle sizes requires advanced architectural patterns.

Context API

The Context API solves the problem of prop drilling. It allows global data—such as UI themes, localization languages, or user authentication status—to be shared directly with any component in the tree, regardless of depth, without passing props manually at every level.

Portals and Error Boundaries

  • Portals (ReactDOM.createPortal): Renders a child element into a DOM node that exists entirely outside the current component's DOM hierarchy.

  • Real-world application: Modals, tooltips, and floating menus. Portals prevent CSS properties like overflow: hidden or z-index on parent containers from clipping or hiding the overlay.

  • Error Boundaries: specialized Class components designed to catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of crashing the whole application.

  • static getDerivedStateFromError: Used to update state and render a fallback UI.

  • componentDidCatch: Used to log the error information to an external monitoring service.

Higher-Order Components (HOC)

A Higher-Order Component (HOC) is a pattern for reusing component logic. Conceptually, a HOC is a function that takes a component as an argument and returns a new, enhanced component. It injects additional props or behaviors (e.g., withRouter or connect in Redux).

Lazy Loading and Suspense

To reduce initial load times, React supports dynamically importing components only when they are needed.

  • React.lazy: Wraps dynamic imports to facilitate lazy loading.
  • <Suspense>: A component that wraps the lazy-loaded components. It utilizes a fallback prop (such as a <Spinner/>) to display temporary content while the requested component chunk is being downloaded over the network.

Summary: Context circumvents prop drilling, Portals break out of CSS hierarchies, Error Boundaries prevent catastrophic crashes, HOCs share structural logic, and Suspense provides graceful loading states.

Self-Check: Can a functional component be an Error Boundary using hooks, or is a Class component strictly required?