Unit 1 - Notes

INT252

Unit 1: Refreshing JavaScript and ReactJS installation

1. ES6 Refresher

ECMAScript 2015 (ES6) introduced significant features to JavaScript that are essential for modern React development.

Variables: let, const, and var

  • var:
    • Scope: Function scoped. If declared outside a function, it is globally scoped.
    • Hoisting: Variables are hoisted and initialized with undefined.
    • Re-declaration: Can be re-declared and updated.
  • let:
    • Scope: Block scoped (only exists within the {} block where it is defined).
    • Hoisting: Hoisted but not initialized (Temporal Dead Zone).
    • Re-declaration: Can be updated but not re-declared in the same scope.
  • const:
    • Scope: Block scoped.
    • Behavior: Constant reference. The identifier cannot be reassigned. However, if the value is an object or array, its properties/elements can still be modified.

JAVASCRIPT
if (true) {
  var a = 1;
  let b = 2;
  const c = 3;
}
console.log(a); // 1
// console.log(b); // ReferenceError
// console.log(c); // ReferenceError

Arrow Functions

A concise syntax for writing function expressions.

  • Syntax: Removes the function keyword.
  • Implicit Return: If the function body is a single expression, brackets {} and the return keyword can be omitted.
  • this keyword: Arrow functions do not have their own this. They inherit this from the surrounding code (lexical scoping). This is crucial in React class components (though less relevant in functional components).

JAVASCRIPT
// Traditional
function add(a, b) {
  return a + b;
}

// Arrow Function (Explicit Return)
const add = (a, b) => {
  return a + b;
};

// Arrow Function (Implicit Return)
const multiply = (a, b) => a * b;

Classes

Syntactic sugar over JavaScript's existing prototype-based inheritance. Essential for React Class Components (legacy).

  • Constructor: A special method for creating and initializing an object created with a class.
  • Inheritance: Used via the extends keyword.

JAVASCRIPT
class Person {
  constructor(name) {
    this.name = name;
  }
  greet() {
    return `Hello, ${this.name}`;
  }
}

class Student extends Person {
  constructor(name, course) {
    super(name); // Calls parent constructor
    this.course = course;
  }
}

Destructuring

Allows unpacking values from arrays or properties from objects into distinct variables.

  • Object Destructuring:
    JAVASCRIPT
        const user = { id: 1, name: 'Alice', age: 25 };
        const { name, age } = user;
        // name is 'Alice', age is 25
        
  • Array Destructuring:
    JAVASCRIPT
        const colors = ['red', 'green'];
        const [primary, secondary] = colors;
        // primary is 'red'
        

Spread and Rest Operators (...)

  • Spread Operator: Expands an iterable (like an array) into individual elements. Used heavily in React to copy state immutably.
    JAVASCRIPT
        const oldArr = [1, 2];
        const newArr = [...oldArr, 3, 4]; // [1, 2, 3, 4]
        
        const obj1 = { a: 1 };
        const obj2 = { ...obj1, b: 2 }; // { a: 1, b: 2 }
        
  • Rest Operator: Collects multiple elements into a single array (usually in function arguments).
    JAVASCRIPT
        function sum(...numbers) {
          return numbers.reduce((a, b) => a + b);
        }
        

Modules (Import/Export)

JavaScript modules allow breaking code into separate files.

  • Named Export: Can export multiple values. Must be imported with exact names in curly braces.
    JAVASCRIPT
        // math.js
        export const add = (a, b) => a + b;
        // main.js
        import { add } from './math';
        
  • Default Export: One export per file. Can be imported with any name.
    JAVASCRIPT
        // user.js
        export default function User() { ... }
        // main.js
        import UserProfile from './user';
        

2. Array Methods

Modern React relies heavily on array manipulation for rendering lists and managing data.

  1. map(): Creates a new array by applying a function to every element. Most used method in React for rendering lists.
    JAVASCRIPT
        const nums = [1, 2, 3];
        const doubled = nums.map(n => n * 2); // [2, 4, 6]
        
  2. filter(): Creates a new array with all elements that pass the test implemented by the provided function.
    JAVASCRIPT
        const nums = [1, 2, 3, 4];
        const evens = nums.filter(n => n % 2 === 0); // [2, 4]
        
  3. reduce(): Executes a reducer function on each element, resulting in a single output value.
    JAVASCRIPT
        const nums = [1, 2, 3];
        const sum = nums.reduce((acc, curr) => acc + curr, 0); // 6
        
  4. forEach(): Executes a provided function once for each array element. Returns undefined. Used for side effects.
    JAVASCRIPT
        nums.forEach(n => console.log(n));
        
  5. find(): Returns the value of the first element that satisfies the provided testing function.
    JAVASCRIPT
        const nums = [5, 12, 8];
        const result = nums.find(n => n > 10); // 12
        
  6. every(): Tests whether all elements in the array pass the test. Returns Boolean.
    JAVASCRIPT
        const nums = [10, 20, 30];
        const allPositive = nums.every(n => n > 0); // true
        
  7. concat(): Merges two or more arrays. Returns a new array.
    JAVASCRIPT
        const a = [1, 2];
        const b = [3, 4];
        const c = a.concat(b); // [1, 2, 3, 4]
        
  8. Array.from(): Creates a new, shallow-copied Array instance from an array-like or iterable object.
    JAVASCRIPT
        const str = 'foo';
        const arr = Array.from(str); // ["f", "o", "o"]
        
  9. indexOf(): Returns the first index at which a given element can be found, or -1 if it is not present.
    JAVASCRIPT
        const animals = ['ant', 'bison', 'camel'];
        console.log(animals.indexOf('bison')); // 1
        
  10. reverse(): Reverses an array in place. The first array element becomes the last, and the last becomes the first.
    JAVASCRIPT
        const arr = [1, 2, 3];
        arr.reverse(); // arr is now [3, 2, 1]
        

3. Introduction to SPA, MPA, and React Framework

SPA (Single Page Application)

  • Definition: A web application that loads a single HTML page and dynamically updates that page as the user interacts with the app.
  • Mechanism: JavaScript intercepts navigation actions, fetches JSON data from the server, and updates the DOM.
  • Pros: Smoother user experience (no white flash between pages), faster transitions, behaves like a native app.
  • Cons: Initial load can be heavy, SEO requires extra configuration (Server-Side Rendering).
  • Examples: Gmail, Trello, React apps.

MPA (Multi-Page Application)

  • Definition: Traditional web architecture where every interaction requests a new HTML document from the server.
  • Mechanism: The browser fully reloads the page on navigation.
  • Pros: Excellent SEO out of the box, simple to scale.
  • Cons: Slower interaction speed, full page reloads interrupt user experience.
  • Examples: Amazon, eBay (traditional parts), Standard WordPress sites.

React Framework (Library)

  • What is it?: A JavaScript library for building user interfaces, maintained by Meta (Facebook).
  • Philosophy:
    • Component-Based: UI is built by combining small, isolated, reusable pieces of code called components.
    • Declarative: You tell React what the UI should look like based on the state, and React handles how to update the DOM.
    • Virtual DOM: React keeps a lightweight copy of the DOM in memory. When data changes, it compares the Virtual DOM with the real DOM (Diffing) and only updates what changed (Reconciliation).

4. Installation and Environment

React Environment Prerequisites

To run React locally, you need:

  1. Node.js: A runtime environment to execute JavaScript outside the browser.
  2. NPM (Node Package Manager): Included with Node.js, used to manage dependencies.
  3. Code Editor: VS Code is the industry standard.

Installing React

There are two primary ways to scaffold a new React project:

1. Create React App (CRA)

The traditional method recommended for beginners for a long time.

  • Command:
    BASH
        npx create-react-app my-app
        cd my-app
        npm start
        
  • Features: Zero configuration, hides Webpack/Babel logic.
  • Cons: Can be slow to start/build as the project grows.

2. Vite (Modern Standard)

A build tool that aims to provide a faster and leaner development experience.

  • Command:
    BASH
        npm create vite@latest my-app -- --template react
        cd my-app
        npm install
        npm run dev
        
  • Features: Extremely fast server start (uses native ES modules), optimized build.

Folder Structure (Standard Vite/CRA)

  • node_modules/: Contains all project dependencies.
  • public/: Static assets. Contains index.html (the single HTML file in SPA).
  • src/: The main development folder.
    • App.js or App.jsx: The root component.
    • main.jsx or index.js: The JavaScript entry point where React attaches to the DOM.
    • package.json: Lists dependencies and scripts (start, build, test).

5. JSX and Component Basics

Understanding Components

Components are the building blocks of React.

  • Function Components: JavaScript functions that return JSX. (Modern Standard).
  • Class Components: ES6 classes that extend React.Component and have a render() method. (Legacy).

JSX (JavaScript XML)

JSX is a syntax extension for JavaScript. It looks like HTML but allows you to write HTML structures within JavaScript files.

Why use JSX?
It visualizes the UI structure within the logic code, making it easier to understand the component's layout.

React.createElement() vs. JSX

Browsers cannot read JSX. It must be compiled (by Babel) into standard JavaScript calls using React.createElement().

Using JSX:

JSX
const element = <h1 className="greeting">Hello, world!</h1>;

Using createElement() (What the browser actually receives):

JAVASCRIPT
// Arguments: type, props, ...children
const element = React.createElement(
  'h1',
  { className: 'greeting' },
  'Hello, world!'
);

createElement() Arguments:

  1. type: The HTML tag string (e.g., 'div', 'h1') or a React Component.
  2. props: An object containing attributes (e.g., {id: 'header', className: 'main'}) or null.
  3. children: The content between the tags (text, or other elements).

JSX Expressions

You can embed any valid JavaScript expression inside JSX using curly braces {}.

JSX
const name = 'John';
const user = { firstName: 'Jane', lastName: 'Doe' };

const element = (
  <div>
    <h1>Hello, {name}</h1>
    <p>Full Name: {user.firstName + ' ' + user.lastName}</p>
    <p>Math: {2 + 2}</p>
    {/* Ternary Operator */}
    <p>Status: {user.firstName ? 'Active' : 'Inactive'}</p>
  </div>
);

Note: You cannot use statements (like if, for) directly inside {}; use ternary operators or map instead.

Rendering Elements into DOM

To render a React application, we need a root DOM node (usually a div with id="root" in index.html).

React 18 (Modern Syntax):
Uses the Concurrent Mode API.

JAVASCRIPT
// usually in main.jsx or index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

// 1. Select the HTML root element
const rootElement = document.getElementById('root');

// 2. Create a React Root
const root = ReactDOM.createRoot(rootElement);

// 3. Render the component
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Legacy Syntax (React 17 and older):

JAVASCRIPT
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));