MODULE 1

JavaScript Essentials for React

Master the JavaScript fundamentals you need to understand and build React applications

What You'll Learn

In this module, you'll learn the JavaScript concepts that form the foundation of React development. Understanding these fundamentals is crucial before moving to React itself.

What is JavaScript?

JavaScript is a programming language that runs in web browsers and servers. It allows you to make web pages interactive. React is built on JavaScript, so understanding JS is essential.

Key Facts about JavaScript:

Variables (let, const, var)

Variables store data values. In modern JavaScript, you should use let and const instead of the older var.

const (constant)

Use const by default for variables that won't change:

const name = "Sarah";
const age = 25;
const isStudent = true;

Once declared with const, you can't reassign the variable:

const count = 10;
count = 20;  // ❌ Error: Assignment to constant variable
πŸ’‘ Pro Tip: Always start with const. Use let only when you need to reassign the variable.

let (block-scoped variable)

Use let when you need to change the value:

let count = 0;
count = count + 1;  // βœ… This works
console.log(count);  // 1

var (avoid it)

The older var keyword has confusing behavior. Avoid it in modern JavaScript:

var oldStyle = "outdated";  // ❌ Avoid this

Data Types

JavaScript has different types of data:

Numbers

const age = 25;
const price = 19.99;
const negative = -5;
const result = 10 + 5;  // 15

Strings

Text data enclosed in quotes:

const name = "John";
const greeting = 'Hello';
const message = `Hello, my name is ${name}`;  // Template literal

Booleans

True or false values:

const isLoggedIn = true;
const isEmpty = false;
const isStudent = age < 18;

Objects

Collections of key-value pairs:

const person = {
  name: "Alice",
  age: 30,
  city: "New York"
};

console.log(person.name);  // "Alice"
console.log(person["age"]);  // 30

Arrays

Ordered lists of values:

const numbers = [1, 2, 3, 4, 5];
const mixed = [1, "two", true, { name: "John" }];

console.log(numbers[0]);  // 1
console.log(numbers.length);  // 5

null and undefined

const empty = null;  // Intentionally empty
let notAssigned;  // undefined (no value assigned yet)

console.log(empty);  // null
console.log(notAssigned);  // undefined

Operators

Operators perform operations on values.

Arithmetic Operators

const a = 10;
const b = 3;

console.log(a + b);  // 13 (addition)
console.log(a - b);  // 7 (subtraction)
console.log(a * b);  // 30 (multiplication)
console.log(a / b);  // 3.33... (division)
console.log(a % b);  // 1 (modulo - remainder)
console.log(a ** 2);  // 100 (exponentiation)

Comparison Operators

5 > 3    // true
5 < 3    // false
5 >= 5   // true
5 <= 4   // false
5 == "5"  // true (loose equality - don't use)
5 === "5" // false (strict equality - use this)
5 !== "5" // true
⚠️ Important: Always use === and !== for comparison. Avoid == and !=.

Logical Operators

true && true   // true (AND)
true && false  // false
true || false  // true (OR)
false || false // false
!true          // false (NOT)

Assignment Operators

let x = 5;
x += 3;    // x = x + 3; β†’ 8
x -= 2;    // x = x - 2; β†’ 6
x *= 2;    // x = x * 2; β†’ 12
x /= 3;    // x = x / 3; β†’ 4

Control Flow (if, switch)

if / else if / else

Make decisions based on conditions:

const age = 25;

if (age < 13) {
  console.log("Child");
} else if (age < 18) {
  console.log("Teenager");
} else {
  console.log("Adult");
}

switch Statement

Choose from multiple options:

const day = 3;
let dayName;

switch (day) {
  case 1:
    dayName = "Monday";
    break;
  case 2:
    dayName = "Tuesday";
    break;
  case 3:
    dayName = "Wednesday";
    break;
  default:
    dayName = "Unknown";
}

console.log(dayName);  // "Wednesday"

Loops

for Loop

Repeat code a specific number of times:

for (let i = 0; i < 5; i++) {
  console.log(i);  // 0, 1, 2, 3, 4
}

while Loop

let count = 0;
while (count < 3) {
  console.log(count);  // 0, 1, 2
  count++;
}

for...of Loop

Loop through array values:

const fruits = ["apple", "banana", "orange"];

for (const fruit of fruits) {
  console.log(fruit);  // "apple", "banana", "orange"
}

forEach Method

Modern way to loop through arrays:

const numbers = [1, 2, 3];

numbers.forEach((num, index) => {
  console.log(index, num);  // 0 1, 1 2, 2 3
});

Functions

Functions are reusable blocks of code:

Function Declaration

function greet(name) {
  return "Hello, " + name;
}

console.log(greet("Alice"));  // "Hello, Alice"

Function Expression

const add = function(a, b) {
  return a + b;
};

console.log(add(5, 3));  // 8

Arrow Functions (Modern)

Shorter syntax, especially useful in React:

const multiply = (a, b) => {
  return a * b;
};

// Short form (implicit return)
const square = (x) => x * x;

console.log(multiply(4, 5));  // 20
console.log(square(5));  // 25

Default Parameters

const introduce = (name = "Guest", age = 18) => {
  return `${name} is ${age} years old`;
};

console.log(introduce("Bob", 25));  // "Bob is 25 years old"
console.log(introduce("Alice"));  // "Alice is 18 years old"

Scope & Closures

Scope

Scope determines where a variable is accessible:

const globalVar = "global";

function myFunction() {
  const localVar = "local";
  console.log(globalVar);  // βœ… Can access global
  console.log(localVar);   // βœ… Can access local
}

console.log(globalVar);  // βœ… Can access global
console.log(localVar);   // ❌ Error: localVar not defined

Closures

A closure is a function that has access to variables from its outer scope:

function makeCounter() {
  let count = 0;  // This variable is "closed over"
  
  return function() {
    count++;
    return count;
  };
}

const counter = makeCounter();
console.log(counter());  // 1
console.log(counter());  // 2
console.log(counter());  // 3

This is powerful in React for managing state and callbacks.

Arrays & Array Methods

Arrays are essential in React. Learn these methods:

map (Transform items)

Create a new array by transforming each item:

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(num => num * 2);

console.log(doubled);  // [2, 4, 6, 8]

filter (Select items)

Create a new array with only items that match a condition:

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(num => num % 2 === 0);

console.log(evenNumbers);  // [2, 4]

reduce (Combine items)

Combine all items into a single value:

const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((total, num) => total + num, 0);

console.log(sum);  // 10

find (Get first match)

const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Charlie" }
];

const user = users.find(u => u.id === 2);
console.log(user);  // { id: 2, name: "Bob" }

includes (Check if exists)

const fruits = ["apple", "banana", "orange"];
console.log(fruits.includes("banana"));  // true
console.log(fruits.includes("grape"));   // false
Array methods illustration

Objects & Destructuring

Creating Objects

const person = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
  hobbies: ["reading", "gaming"],
  address: {
    city: "New York",
    zipCode: "10001"
  }
};

console.log(person.firstName);        // "John"
console.log(person["lastName"]);      // "Doe"
console.log(person.address.city);     // "New York"

Object Destructuring

Extract values from objects into variables:

const person = { name: "Alice", age: 25, city: "Boston" };

// Destructuring
const { name, age } = person;
console.log(name);  // "Alice"
console.log(age);   // 25

Function Parameters Destructuring

Destructure directly in function parameters:

const printUser = ({ name, age }) => {
  console.log(`${name} is ${age} years old`);
};

const user = { name: "Bob", age: 30, city: "NYC" };
printUser(user);  // "Bob is 30 years old"

Spread & Rest Operators

Spread Operator (...)

Spread values from arrays or objects:

// Arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];
console.log(combined);  // [1, 2, 3, 4, 5, 6]

// Objects
const user = { name: "Alice", age: 25 };
const updatedUser = { ...user, age: 26 };
console.log(updatedUser);  // { name: "Alice", age: 26 }

Rest Operator (...)

Collect multiple arguments into an array:

const sum = (...numbers) => {
  return numbers.reduce((a, b) => a + b, 0);
};

console.log(sum(1, 2, 3, 4));  // 10

Template Literals

String interpolation with backticks:

const name = "Alice";
const age = 25;

// Old way (avoid)
const msg1 = "Hello, " + name + "! You are " + age + " years old.";

// Modern way (use this)
const msg2 = `Hello, ${name}! You are ${age} years old.`;

console.log(msg2);  // "Hello, Alice! You are 25 years old."

ES6 Modules (import/export)

Organize code into reusable modules:

Exporting

// math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;

export default function multiply(a, b) {
  return a * b;
}

Importing

// app.js
import multiply, { add, subtract } from './math.js';

console.log(add(5, 3));        // 8
console.log(subtract(5, 3));   // 2
console.log(multiply(5, 3));   // 15

DOM Concepts (Brief Overview)

The DOM (Document Object Model) is the structure of a web page. JavaScript can manipulate it:

// Select elements
const element = document.getElementById("myId");
const elements = document.querySelectorAll(".myClass");

// Change content
element.textContent = "New text";
element.innerHTML = "

HTML content

"; // Add/remove classes element.classList.add("active"); element.classList.remove("hidden"); // Listen for events element.addEventListener("click", () => { console.log("Clicked!"); });
πŸ’‘ Note: React abstracts away direct DOM manipulation. You won't write code like this in React!

Asynchronous JavaScript

Modern web applications need to perform operations that take time (like fetching data).

setTimeout

Execute code after a delay:

console.log("Start");

setTimeout(() => {
  console.log("This runs after 2 seconds");
}, 2000);

console.log("End");

Promises

Represent a value that may be available now, or in the future:

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Success!");
  }, 1000);
});

myPromise.then(result => {
  console.log(result);  // "Success!"
}).catch(error => {
  console.log(error);
});

async / await

Modern way to handle asynchronous code:

async function getData() {
  try {
    const response = await fetch("https://api.example.com/data");
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.log("Error:", error);
  }
}

getData();

Error Handling (try/catch)

Handle errors gracefully:

try {
  const result = riskyFunction();
  console.log(result);
} catch (error) {
  console.log("An error occurred:", error.message);
} finally {
  console.log("This always runs");
}

JavaScript Best Practices for React

  1. Use const by default: It prevents accidental reassignments.
  2. Use const/let, never var: var has confusing scoping rules.
  3. Use === instead of ==: Avoid type coercion issues.
  4. Use arrow functions: They have better this binding.
  5. Keep functions pure: Same input = same output, no side effects.
  6. Use destructuring: It makes code cleaner and easier to read.
  7. Use template literals: More readable than string concatenation.
  8. Avoid mutating arrays/objects: Create new ones with spread operator.
  9. Use meaningful variable names: Code is read more than written.
  10. Handle errors properly: Don't ignore potential failures.
JavaScript fundamentals illustration

Key Takeaways

⚠️ Practice Now: Before moving to the next module, write code for each of these concepts. Open your browser console (F12) and practice JavaScript. Type out the examples, modify them, and experiment!

Recommended Practice Projects