Unit 1: Refreshing JavaScript and React Fundamentals

INT252 — Web App Development With Reactjs 11 min read

I. Orientation — JavaScript as the Foundation of React

React is a JavaScript library for building user interfaces through reusable components and declarative descriptions of UI state. Modern React relies heavily on ECMAScript 2015+ features, functional programming, immutable updates, modules, and browser tooling.

  • Governing principle: A React interface should be described as a predictable function of application state: UI = f(state).
  • Core language: JSX ultimately becomes JavaScript, so arrays, objects, functions, scopes, and modules remain fundamental.
  • Data convention: State and props are treated as immutable values rather than modified directly.
  • Architectural unit: Applications are assembled from small, reusable components with clear responsibilities.
  • Rendering model: React compares render results and updates only the required parts of the browser DOM.
  • Development model: Tools such as Vite provide source transformation, module handling, development servers, and production builds.

II. Modern JavaScript Syntax — Functions, Data, and Modules

Modern JavaScript syntax makes React components and data operations more concise, composable, and predictable.

A. Arrow functions

Arrow functions provide compact function expressions and inherit this lexically from their surrounding scope.

  • Syntax: A single expression has an implicit return; multiple statements require braces and an explicit return.
JS
const square = n => n * n;
const add = (a, b) => {
  return a + b;
};
  • React use: Components, event handlers, and array callbacks commonly use arrows: items.map(item => <li>{item}</li>).
  • Lexical this: Arrow functions do not create their own this, arguments, or prototype; therefore, they are unsuitable as constructors.
  • Object return: Parentheses distinguish an object literal from a function body: const makeUser = name => ({ name });.

B. Block-scoped variables using let and const

let and const restrict bindings to the nearest block, reducing accidental scope leakage.

  • const binding: Must be initialized and cannot be reassigned: const count = 1.
  • let binding: Can be reassigned and suits loop counters or genuinely changing local values.
  • Object qualification: const user = { name: "Asha" } prevents rebinding user, but user.name = "Ravi" remains possible.
  • Best practice: Use const by default and let only when reassignment is necessary; avoid function-scoped var.

C. Array iteration and transformation methods

Array methods process collections without manual index management and are central to rendering lists.

  • map: Produces a new array by transforming every element.
JS
const prices = [10, 20];
const taxed = prices.map(price => price * 1.1);
  • filter: Retains elements satisfying a condition: users.filter(user => user.active).
  • find: Returns the first matching element, while some and every return Boolean results.
  • reduce: Accumulates one result: prices.reduce((sum, price) => sum + price, 0).
  • forEach: Performs side effects but returns undefined; it is not appropriate when a transformed array is required.

D. Destructuring assignments

Destructuring extracts values from arrays or objects into named bindings.

  • Object form: const { name, age } = user selects properties by key.
  • Array form: const [first, second] = colors selects values by position.
  • Renaming and defaults: const { name: displayName, role = "user" } = account.
  • React use: Props are often destructured in parameters: function Card({ title, image }).
  • Nested data: const { address: { city } } = user works only when address exists; optional access may be safer.

E. Spread and rest operators

The ... syntax expands values in one context and collects remaining values in another.

  1. Spread operation:
    • Arrays: const all = [...first, ...second] creates a new outer array.
    • Objects: const updated = { ...user, active: true } copies properties, with later keys overriding earlier ones.
  2. Rest operation:
    • Parameters: const sum = (...numbers) => numbers.reduce((a, n) => a + n, 0).
    • Destructuring: const { id, ...details } = user collects unselected properties.
  • Limitation: Spread performs only a shallow copy, so nested references remain shared.

F. ES modules

ES modules divide code into files with explicit imports and exports.

  • Named export: export const formatDate = value => value.toLocaleDateString();.
  • Named import: import { formatDate } from "./date.js"; must use the exported name unless aliased.
  • Default export: export default App is imported as import App from "./App.jsx";.
  • Static structure: Imports are resolved before execution, enabling bundling and tree-shaking.
  • Browser convention: Local module paths require relative prefixes such as ./ or ../.

III. Predictable Data — Functional and Immutable Techniques

React state comparison works most reliably when transformations produce new values instead of mutating existing ones.

A. Immutability principles

Immutability means preserving an existing value and creating a replacement when data changes.

  • State rule: Avoid state.items.push(item) because it modifies the current array.
  • Immutable update: Use setItems(previous => [...previous, item]).
  • Object update: setUser(previous => ({ ...previous, name: "Mina" })) creates a new outer object.
  • Benefit: Previous and next versions remain distinguishable, supporting predictable rendering, debugging, and undo histories.
  • Boundary: JavaScript objects are mutable by default; immutability is primarily a programming discipline.

B. Functional programming concepts relevant to React

Functional programming models computation through functions, composition, and transformations with controlled side effects.

  • Pure function: Given identical inputs, it returns the same output and does not modify external data: double(3) always returns 6.
  • Component model: A component conceptually maps props and state to JSX.
  • Higher-order function: map, filter, and reduce receive callback functions and return transformed results.
  • Composition: Complex interfaces are built by combining components, such as Page containing Header and ProductList.
  • Side effects: Network requests, subscriptions, and DOM integration belong in controlled mechanisms such as useEffect, not directly in rendering.

C. Shallow and deep copying mechanisms

Copying determines whether nested data is shared or independently duplicated.

  1. Shallow copy:
    • Mechanisms: Object spread, array spread, Object.assign, slice, and Array.from.
    • Effect: Only the outer container is new.
JS
const original = { profile: { city: "Pune" } };
const copy = { ...original };
copy.profile.city = "Delhi"; // also affects original.profile.city
  1. Deep copy:
    • Mechanism: structuredClone(original) recursively copies supported values.
    • Limitations: Functions and some host objects cannot be cloned; JSON conversion loses values such as undefined and cannot represent cycles.
  • Preferred update: Copy only changed paths rather than deep-cloning an entire state tree.

D. Referential equality and state comparison

Referential equality checks whether objects or functions are the same allocated value, not merely structurally similar.

  • Primitive comparison: 3 === 3 is true because primitive values are compared by value.
  • Reference comparison: { x: 1 } === { x: 1 } is false because the objects occupy different references.
  • Mutation problem: Updating an object in place preserves its reference, making change detection less reliable.
  • React relevance: React and optimization tools such as React.memo commonly use shallow or identity-based comparisons.
  • Stability: useMemo and useCallback can preserve references when identity matters, but should be used only for justified optimization.

IV. Web Application Models and React Architecture

React’s architecture is best understood by comparing navigation models and examining how components describe interfaces.

A. Single Page Applications and Multi Page Applications

SPAs and MPAs differ mainly in navigation, document loading, and responsibility for rendering.

  1. Single Page Application (SPA):
    • Navigation: Loads an initial HTML document, then updates views through client-side JavaScript.
    • Strength: Enables fluid transitions and persistent client state.
    • Cost: Requires careful routing, loading-state, accessibility, and search-engine considerations.
  2. Multi Page Application (MPA):
    • Navigation: Requests a new HTML document from the server for each major page.
    • Strength: Offers straightforward server rendering and page isolation.
    • Cost: Full-page navigation may reset client memory and reload shared resources.

B. React philosophy and declarative UI paradigm

React declares what the interface should look like for current data rather than prescribing each DOM operation.

  • Declarative form: {loggedIn ? <Dashboard /> : <Login />} expresses the desired result.
  • Contrast: Imperative code might manually locate an element, clear it, create nodes, and attach them.
  • One-way flow: Parents pass data downward through props; child events can request state changes through callbacks.
  • State-driven UI: Changing state triggers another render description, allowing React to coordinate DOM updates.

C. Component-based architecture

Component-based architecture divides the UI into independent, reusable units.

  • Encapsulation: A ProductCard can contain its own markup, behavior, and styling concerns.
  • Props: Read-only inputs customize instances: <ProductCard name="Keyboard" price={50} />.
  • State: Local memory represents changing information such as whether a menu is open.
  • Composition: Prefer assembling components through children and props over inheritance.
  • Responsibility: Components should remain focused; unrelated data access and presentation logic should be separated when complexity grows.

V. React Setup and Project Organization

A modern React project combines a development server, transformation pipeline, package manager, and maintainable source structure.

A. Setting up React applications using Vite

Vite creates lightweight React projects and provides fast development updates.

  • Creation:
BASH
npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev
  • Entry files: index.html supplies the root element, while src/main.jsx initializes React.
  • Scripts: npm run dev starts development, npm run build creates production assets, and npm run preview tests the build locally.
  • Configuration: Environment variables exposed to client code use the VITE_ prefix and must never contain secrets.

B. Modern React development environment and tooling

Modern tooling improves correctness, debugging, transformation, and delivery.

  • Node.js and npm: Node runs build tools; npm installs dependencies recorded in package.json.
  • Fast Refresh: Vite updates edited modules while often preserving component state.
  • JSX transformation: The toolchain converts JSX into JavaScript React element creation instructions.
  • Linting: ESLint detects suspicious patterns and enforces rules, including React Hooks conventions.
  • Browser support: React Developer Tools exposes component trees, props, state, and profiling information.
  • Production build: Bundling, minification, and dead-code elimination reduce deployable assets.

C. Feature-based project folder structure and best practices

Feature-based organization groups files by application capability rather than only by technical type.

  • Example structure:
TEXT
src/
  app/
  features/
    products/
      ProductList.jsx
      productApi.js
  components/
  hooks/
  utils/
  main.jsx
  • Feature locality: Product-specific components and API logic remain inside features/products.
  • Shared code: Truly reusable UI belongs in components; cross-feature hooks and utilities use hooks and utils.
  • Best practices: Use consistent names, avoid oversized components, keep imports directional, and remove duplicated abstractions.
  • Scalability: Begin simply and introduce folders only when real responsibilities emerge.

VI. JSX and Browser Rendering

JSX provides a readable syntax for describing React element trees, which React mounts into a browser container.

A. JSX syntax and expressions

JSX resembles HTML but follows JavaScript expression and property conventions.

  • Expressions: Braces evaluate JavaScript: <p>{user.name}</p>.
  • Attributes: Use className instead of class, and camelCase names such as onClick.
  • Single parent: Adjacent elements require a wrapper or fragment: <>...</>.
  • Closing rules: Tags must close, including <img />.
  • Values: Strings may use quotes; numbers, variables, objects, and functions use braces.
  • Safety: React escapes interpolated strings by default, reducing HTML-injection risk.

B. Rendering components into the DOM

React creates a root attached to an existing DOM node and renders the component tree into it.

  • HTML container: Vite’s index.html commonly contains <div id="root"></div>.
  • Root creation:
JSX
import { createRoot } from "react-dom/client";
import App from "./App.jsx";

createRoot(document.getElementById("root")).render(<App />);
  • Ownership: React manages DOM content inside the root; direct manual changes there can conflict with reconciliation.
  • Strict mode: Development projects may wrap App in React.StrictMode to expose unsafe patterns.

VII. Component Execution and React’s Update Mechanism

React repeatedly evaluates components to produce element descriptions and reconciles them with previous results.

A. Functional components and render lifecycle

A functional component is a JavaScript function that returns renderable JSX.

  • Definition: Component names begin with uppercase letters.
JSX
function Greeting({ name }) {
  return <h1>Hello, {name}</h1>;
}
  • Render trigger: Initial mounting, state updates, parent rendering, or context changes may cause execution.
  • Render phase: React calls components and calculates the next UI; rendering should remain pure.
  • Commit phase: React applies necessary DOM changes and then runs relevant effects.
  • Important distinction: A render does not necessarily mean a DOM mutation; the calculated output may be unchanged.

B. Introduction to Virtual DOM and reconciliation process

The Virtual DOM is React’s in-memory representation of the element tree used to calculate efficient UI updates.

  • New tree: Each render produces React elements describing the desired interface.
  • Reconciliation: React compares the new tree with the previous tree by element type, position, props, and keys.
  • Type rule: Changing <Button /> to <Link /> generally replaces that subtree; matching types allow updates.
  • List keys: Stable keys such as database IDs help React track item identity across insertion, deletion, and reordering.
  • Commit: Only identified host changes—such as text, attributes, or DOM nodes—are applied.
  • Clarification: The Virtual DOM does not eliminate comparison costs; its value lies in predictable declarative updates and coordinated DOM mutation.