INT252Semester 5 • 3 CreditsElective Subjects

Web App Development With Reactjs

This course develops skills in building React.js web applications using modern JavaScript, JSX, reusable functional components, React hooks, forms and validation, client-side routing, API-based data fetching, and shared state management.

6 Units • Notes • Model Answers • MCQs
Select Course Unit (6 Units)
Active: Unit 1
Unit 1:Unit 1: Refreshing JavaScript and React Fundamentals
7 min read•High-Yield Unit Guide

Unit 1: Refreshing JavaScript and React Fundamentals

Unit 1 Exam Focus & Core Takeaways

Review the core definitions, standard architectures, and syntax patterns below. Pay special attention to sections highlighted with bullet points for your mid-term and end-term subjective questions.

Unit 1: Refreshing JavaScript and React Fundamentals

1. Modern JavaScript (ES6+) Essentials for React

Modern React development relies extensively on ECMAScript 2015 (ES6) and subsequent language specifications. Mastering these core JavaScript concepts is critical for reading, writing, and architecting efficient React web applications.

Variable Scoping: let, const, and var

  • var (ES5 Legacy): Function-scoped or globally scoped. Variables declared with var are hoisted to the top of their function context and initialized with undefined. They can be redeclared and reassigned, leading to unpredictable scope leaks and bugs inside loops and conditionals.
  • let (ES6): Block-scoped (confined to {}). Hoisted to the top of the enclosing block but not initialized, residing in the Temporal Dead Zone (TDZ) from the start of the block until declaration execution. Can be reassigned but cannot be redeclared within the same scope.
  • const (ES6): Block-scoped and immutable binding. Must be initialized at declaration. The variable identifier cannot be reassigned. Note that while primitive values bound to const cannot change, complex objects and arrays remain mutable (their properties or elements can be modified unless frozen via Object.freeze()).

Arrow Functions (=>)

Arrow functions introduce concise syntax and unique lexical behavior:

  • Syntax Variations:
    • Single parameter without parentheses: x => x * 2
    • Implicit return for single expressions: (a, b) => a + b
    • Explicit return required when using braces: (a, b) => { return a + b; }
    • Returning object literals implicitly requires wrapping parentheses: () => ({ key: 'value' })
  • Lexical this Binding: Arrow functions do not bind their own this, arguments, super, or new.target. Instead, they inherit this from the enclosing lexical execution context at the time of definition. This makes them ideal for React callbacks and event handlers, avoiding manual .bind(this) calls common in legacy class components.

Template Literals

Enclosed in backticks (`) rather than single or double quotes:

  • Supports multi-line strings without escape sequences (\n).
  • Embeds JavaScript expressions via string interpolation: ${expression}.
  • Enables Tagged Templates, which are leveraged heavily in CSS-in-JS libraries like styled-components.

2. Destructuring, Spread, Rest, and Functional Array Methods

Destructuring Assignment

Unpacks values from arrays or properties from objects into distinct variables:

  • Object Destructuring:
    javascript
    const user = { id: 101, username: 'dev_alex', role: 'admin' };
    const { username, role: userRole, status = 'active' } = user;
    
    Enables property renaming (role: userRole) and fallback default values (status = 'active'). Heavily used in React to destructure component props and hook returns.
  • Array Destructuring:
    javascript
    const coordinates = [45.12, -93.28];
    const [latitude, longitude] = coordinates;
    
    Values are assigned by index position rather than property keys. This is the foundation of React hooks like const [count, setCount] = useState(0);.

Spread (...) and Rest (...) Operators

Although sharing the same ellipsis syntax (...), they serve opposing operations based on context:

  • Spread Operator: Expands an iterable (array, string) or object into individual elements or properties:
    • Copying/Cloning arrays: const clone = [...original];
    • Merging objects: const updatedUser = { ...user, active: true };
    • Immutability Rule: React requires immutable state updates. Spread operators create shallow copies, enabling state updates without mutating existing state objects.
  • Rest Parameter: Condenses multiple elements or arguments into a single array:
    • Function definitions: function sum(...numbers) { return numbers.reduce((a, b) => a + b, 0); }
    • Object destructuring: const { id, ...otherProps } = componentProps;

Higher-Order Array Methods

React applications favor declarative, functional programming over imperative for loops:

  • map(): Transforms every element in an array and returns a brand-new array of identical length. Crucial for converting raw data arrays into lists of JSX elements.
  • filter(): Evaluates a predicate function and returns a new array containing only elements that evaluate to truthy. Used for searching and deleting items immutably.
  • reduce(): Accumulates elements into a single aggregate result (number, object, grouped dictionary) by applying a reducer callback across iterations.
  • find() & findIndex(): Locates the first matching element or its index.
  • some() & every(): Evaluates boolean presence across items.

3. Asynchronous JavaScript: Promises and Async/Await

React web applications frequently interact with remote REST APIs and GraphQL backends:

  • Promises: Represent the eventual completion (or failure) of an asynchronous operation and its resulting value. Possess three states: pending, fulfilled, or rejected. Chained using .then(), .catch(), and .finally().
  • Async/Await: Syntactic sugar built on top of Promises that allows asynchronous code to be written in a linear, synchronous-looking style.
    • Functions marked async always return a Promise.
    • The await keyword pauses execution of the async function until the Promise settles.
    • Error handling is managed via standard try...catch blocks.
    • In React, asynchronous operations cannot be passed directly as the primary callback to useEffect; an inner asynchronous function must be declared and invoked within the effect hook.

4. Introduction to React and the Component-Based Model

React is an open-source, declarative, component-driven JavaScript library maintained by Meta and a global open-source community for building modern user interfaces.

Core Philosophy of React

  1. Declarative: Developers declare what the UI should look like for a given state (UI = f(State)), and React automatically handles the underlying DOM mutations to transition between states.
  2. Component-Based: UIs are assembled from encapsulated, reusable, self-contained functional components that manage their own state and render logic.
  3. Unidirectional (Top-Down) Data Flow: Data flows downward from parent components to child components via read-only props. Child components communicate changes back to parents through callbacks passed as props.

Real DOM vs. Virtual DOM (VDOM)

  • The Problem with the Real DOM: The browser DOM tree is heavy and computationally expensive to update. Frequent direct mutations cause costly recalculations of styles, layouts (reflow), and pixel repainting across the viewport.
  • The Virtual DOM: A lightweight, pure JavaScript in-memory representation of the real DOM tree maintained by React.
  • Reconciliation and the Diffing Algorithm:
    1. When state or props change, React generates a new Virtual DOM tree representing the updated UI.
    2. React's Reconciliation engine (React Fiber) compares the new Virtual DOM with the previous snapshot using an optimized O(n)O(n) heuristic diffing algorithm.
    3. React computes the minimal set of changes (the "patch") and efficiently applies only those specific mutations to the real browser DOM in a single batched update.

5. JSX (JavaScript XML) and React Elements

What is JSX?

JSX is a syntax extension for JavaScript that allows developers to write HTML-like markup directly within JavaScript code.

  • JSX is not raw HTML. It is compiled by transpilers like Babel or SWC into standard React.createElement() function invocations.
  • Example:
    jsx
    const element = <h1 className="title">Hello, React!</h1>;
    
    Transpiles to:
    javascript
    const element = React.createElement('h1', { className: 'title' }, 'Hello, React!');
    

Rules and Conventions of JSX

  1. Single Root Element: Every component render must return a single top-level parent element. Multiple sibling elements must be wrapped in a container tag or a React Fragment (<React.Fragment></React.Fragment> or shorthand <></>) to avoid inserting unnecessary extra DOM nodes.
  2. HTML vs. JSX Attributes:
    • class becomes className (since class is a reserved keyword in JavaScript).
    • for becomes htmlFor (since for is a reserved loop keyword).
    • Event handlers use camelCase naming: onClick, onChange, onSubmit.
    • Inline styles are passed as JavaScript objects with camelCase CSS properties: style={{ backgroundColor: 'blue', fontSize: '16px' }}.
  3. Embedding JavaScript Expressions: Any valid JavaScript expression (variables, function calls, arithmetic, ternary operators) can be embedded inside JSX using curly braces {}. Statements like if/else and for loops cannot be placed directly inside JSX brackets and must use ternary operators (condition ? expr1 : expr2) or logical AND operators (condition && <Component />).
  4. Self-Closing Tags: Elements without children must be self-closed: <img src="pic.jpg" alt="" />, <input type="text" />.

6. Rendering Elements and Project Architecture (React 18)

Root DOM Container and createRoot

In modern React (React 18+), client-side applications initialize rendering using the createRoot API from react-dom/client:

javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
  • <React.StrictMode>: A development-only wrapper that helps identify side effects, deprecated API usage, and unhandled memory leaks by deliberately invoking certain component lifecycle functions and hooks twice during rendering.

Thinking in React: Step-by-Step UI Design

  1. Break the user interface design into a component hierarchy based on the Single Responsibility Principle.
  2. Build a static version in React with no state, passing mock data exclusively through props.
  3. Identify the absolute minimal (but complete) representation of dynamic UI state.
  4. Determine which component in the hierarchy should "own" and hold each piece of state.
  5. Add inverse data flow (passing callback handlers down so children can trigger state updates in parent components).