ReactJS-The Beginner Master Class
  • React In the Beginning
    • Lesson 1 - Demo: Build a Simple React App - Fast
    • Lesson 2 - HTML Review
    • Lesson 3 - CSS Review
    • Lesson 4 - Modern JavaScript (JSX) Patterns
    • Lesson 5 - Set up Dev Environment
    • Hands-on Practice
  • React Fundamentals
    • Lesson 1 - Understanding Old vs New Way of Building Web Apps - SPAs
    • Lesson 2 - Motivation for Using React as the Solution to Vanilla JS
    • Lesson 3 - What is ReactJS - How it Works
    • React Code Along from Scratch
    • Lesson 4 - Create and Run a React Project with Vite - Full Overview
    • Lesson 5 - Create Hook by State Management in React
    • Lesson 6 - React Project File and Folder Walkthrough
    • Lesson 7 - JSX and How React Treats the DOM & JSX Compilation(by Babeljs) - Overview
    • Lesson 8 - Understanding the Main Files - App.jsx and main.jsx
    • Lesson 9 - Props and One-Way Data Flow - Overview
    • Lesson 10 - Google Bookshelf App - Ver 1.0
    • Hands-on Practice I
    • Hands-on Practice II
  • React State and Styling
    • Lesson 1 - Pulling Book Data from a Different Data File
    • Lesson 2 - Overview of How State Works in React
    • Lesson 3 - RandomQuote App
    • Lesson 4 - Lifting State Up - React Pattern Overview
    • Hands-On - Simple Counter
  • Forms and Interactivity - Grocery List App
    • Lesson 1 - Setup a Simple Form and Input
    • Lesson 2 - Build Form Profile App Using Multi-input Form Data
    • Hands-on : Build a Grocery List App
  • Connecting to the Backend - Consuming APIs - UseEffect Hook
    • Lesson 1 - Connecting to the Back End - Understanding Side Effects, Hooks and useEffect - Overview
    • Lesson 2 - Fetching Data from the Backend the Right Way with useEffect Hook
    • Lesson 3 - Setting Up Loading State
    • Hands-on :Use Dependency Array and Adding Values that Control Side Effects
  • Solo Project 1
  • RESTful APIs :Build a BookSearch App -Ver 2.0
    • Lesson 1: Build and test RESTful APIs with Postman
    • Lesson 2 - BookShelf App Structure
    • Lesson 3 - Create NavBar.jsx Component
    • Lesson 4 - Create Footer Component
    • Lesson 5 - Create BookList.jsx Component
    • Lesson 6 - Create BookCard.jsx Component
    • Lesson 7 - Creating Custom Hooks - useBooks and api-client
    • Lesson 8 - Controlling Network Activities in React with AbortController
    • Lesson 9 - Show Book Details in a Modal - Working
    • Lesson 10 - Bookshelf App Summary
  • Multi-Page Applications (MPAs)
    • Build a Multi-Page React Application
    • Multi-Page React Application
    • Hands-on Practice
  • Backend Frameworks-NEXT.JS
    • Migrating from React to Next.js
    • Lesson 1: Key Concepts of NodeJS and Express for Backend Web Development
    • Lesson 2: How to set up a new Next.js project
    • Lesson 3: How to create Layouts and Pages
    • Hands-on Practice 1
    • Hands on Practice 2
      • New Project & Folder Structure
      • File-Based Routing
      • Server vs Client Components & Router Hooks
      • Start On The Navbar
      • Navbar Links, Dropdowns & React Icons
      • Active Links & Conditional Rendering
      • Homepage Components
      • Properties Page
      • Property Card Dynamic Data
      • Home Property Listings
      • Custom Not Found & Loading Pages
  • Git and GitHubs
    • Git Installation
    • Git Commands
    • GitHub Repository
    • Hands-on Practice
  • Database in Application
    • React Supabase CRUD
    • Hands-on: Note Taking App
  • NoSQL Database
    • Installing MongoDB Community Edition
    • System Env Path Setting
    • How to use MongoDB Shell
    • How to Connect and Use Mongosh in VS Code via MongoDB Extension
    • MongoDB Guide
  • Solo Project 2
  • Deployment and Web Hosting
    • Lesson 1. React+Vite+TS+Shadcn Project
    • Lesson 2. Deploying a React Vite App to Vercel from Vercel CLI
    • Lesson 3 Connecting to GitHub Repo and Automate Deployment
  • Solo Project 3
  • Final Term Project
    • Level 1 Team Project
    • Level 1 Team Project
    • Level 1 Team Project
    • Level 1 Team Project
    • Level 2 Team Project
    • Level 2 Team Project
    • Level 3 Team Project
    • Level 3 Team Project
Powered by GitBook
On this page
  • Modern JavaScript Programming with React
  • Libraries vs Frameworks
  • Similarities and Differences
  • History
  • Part One: Functions in Modern JavaScript
  • Programming Activities for Part One
  • Part Two: Asynchronous Programming
  • Programming Activities for Part Two
  • Why React?
  • Vanilla JavaScrpt vs React
  1. React In the Beginning

Lesson 4 - Modern JavaScript (JSX) Patterns

Modern JavaScript Programming with React

Libraries vs Frameworks

Libraries
Frameworks

Collection of reusable code

Predetermined architecture - you follow a specified pattern of development

Reduces need to write repetitive/complex things from scratch

You work within the boundaries set by the framework

You control how/when it's used. No/few boundaries.

"Right" and "wrong" ways to use it.

Similarities and Differences

Feature
Libraries
Frameworks

Control

You call the library's functions.

The framework calls your code.

Structure

Focused on specific tasks/tools.

Provides a full application structure.

Scope

Smaller, solves specific problems.

Larger, provides a complete solution.

Flexibility

Very flexible, use what you need.

Less flexible, must follow its rules.

Learning Curve

Generally easier to learn.

Steeper learning curve.

Web Dev Use

UI components (React, jQuery UI), utilities (Lodash), date/time (Moment.js).

Single-page apps (Angular, Vue, React with routing/state management), complex UIs.

Key takeaway:

  • Libraries: Tools you use within your code.

  • Frameworks: Structures you build your code within.


History

Part One: Functions in Modern JavaScript

Lesson Objectives:

  • Function expression and Function Hoisting

  • How Closure Works

  • Understand anonymous functions and their usage.

  • Explore commonly used array methods (map, filter, reduce, etc.).

  • Master arrow functions and their syntax.

  • Destructuring with JavaScript

  • Learn best practices for writing functions, especially in the React ecosystem.

Programming Activities for Part One

Preliminary Concepts

  1. Function Expression

  • A function expression in JavaScript is a way to define a function as part of an expression.

// Assignment to a variable
const myFunc = function(x) { return x * 2; }; // Anonymous function expression
const multiply = function double(x) { return x * 2; }; // Named function expression
// As an argument to another function (callbacks)
const numbers = [1, 2, 3];
const doubled = numbers.map(function(num) { return num * 2; }); // Function expression as callback
// An arrow function syntax (a concise form of function expression)
const square = (x) => x * x; // Arrow function expression
  1. Function Hoisting

  • Function hoisting is a JavaScript behavior where function declarations are conceptually moved to the top of their scope before the code is executed.

// function hoisting
hoistedFunction(); // This works!

function hoistedFunction() {
  console.log("This function is hoisted.");
}

// functionExpression();  // This would cause an error: "functionExpression is not defined"
const functionExpression = function() {
  console.log("Function expressions are NOT hoisted.");
};

hoistedFunction(); // This also works.
  1. Closure

  • A closure in JavaScript is a function that has access to variables from an enclosing (lexical) scope, even after the outer function has finished executing.

// closure
function outerFunction() {
  const outerVar = "Hello from outer";
  let count=0

  function innerFunction() {
    count++;
    console.log(outerVar); // Accessing outerVar from the outer function
    console.log(count); // Accessing innerVar from the inner function
  }

  return innerFunction; // Returning the inner function (the closure)
}

const myCount1 = outerFunction(); // myCount1 now holds the innerFunction
myCount1(); // Output: 1
myCount1(); // Output: 2

Advanced Closure Module Pattern with Data Privacy Encapsulation

The Advanced Closure Module Pattern enhances the classic module pattern by leveraging closures for robust data privacy and encapsulation.

// closure-advanced.js
const createDog = function (name) {  // Outer function: takes the pet's initial name
  let breed; // Private variable to store the pet's breed(initially undefined)

  function setName(newName) { // Inner function: sets the pet's name
    name = newName; // Modifies the 'name' variable in the outer function's scope (closure)
  }

  function getName() { // Inner function: gets the pet's name
    return name; // Accesses the 'name' variable from the outer function's scope (closure)
  }

  function setBreed(newBreed) { // Inner function: sets the pet's breed
    breed= newBreed; // Modifies the 'breed' variable in the outer function's scope (closure)
  }

  function getBreed() { // Inner function: gets the pet's sex
    return breed; // Accesses the 'breed' variable from the outer function's scope (closure)
  }

  // This is the core of the module pattern.  It returns a function.
  return function (password) { // This inner function takes a password
    if (password === "pets") { // Checks if the provided password is correct
      return { // If the password is correct, it returns an object.
        setName, // This object contains the inner functions, effectively making them public.
        getName, // These functions have closure over 'name' and 'breed'.
        setBreed,
        getBreed,
      };
    } else {
      return console.log("Error, incorrect password!"); // If the password is wrong, it logs an error.
    }
  };
};
// Usage:
// correct password
//const getAccessToFluffy = createDog("Fluffy"); // Create a "dog creator" for Fluffy.  It does NOT give access yet.
//const fluffy = getAccessToFluffy("pets"); // Call the returned function with the correct password to get access.
const fluffy = createDog("Fluffy")("pets")
if (fluffy) { // Check to make sure we got access (password was correct)
  console.log(fluffy.getName()); // "Fluffy"
  fluffy.setName("Fluffball");
  console.log(fluffy.getName()); // "Fluffball"

  fluffy.setBreed("Poodle");
  console.log(fluffy.getBreed()); // "Poodle"
}
//wrong password
const getAccessToRover = createDog("Rover");
const rover = getAccessToRover("wrongpassword"); // Incorrect password

if (!rover) {
    console.log("No access to Rover because of wrong password")
}

Activity 1: Using Anonymous Functions

  1. What are Anonymous Functions?

    • Functions without a name.

    • Often used as callbacks in JavaScript.

  2. Hands-On Example:

    • Open your React project and modify a component as follows:

      const AnonymousExample = () => {
        const numbers = [1, 2, 3, 4];
        const squaredNumbers = numbers.map(function (num) {
          return num * num;
        });
      
        return (
          <div>
            <h3>Squared Numbers</h3>
            <p>{squaredNumbers.join(", ")}</p>
          </div>
        );
      };
      
      export default AnonymousExample;
  3. Discuss:

    • Advantages: Concise and directly tied to their context.

    • Use cases: Callbacks for map, filter, and event handlers in React.


Activity 2: Commonly Used Array Methods

  1. Methods Covered:

    • map, filter, reduce, find, some, every, etc.

  2. Task:

    • Create a DataManipulation component:

      import React from 'react';
      
      function DataManipulation() {
        const products = [
          { id: 1, name: 'Laptop', price: 1200, category: 'Electronics' },
          { id: 2, name: 'Keyboard', price: 75, category: 'Electronics' },
          { id: 3, name: 'Book', price: 25, category: 'Books' },
          { id: 4, name: 'Mouse', price: 30, category: 'Electronics' },
          { id: 5, name: 'Notebook', price: 10, category: 'Books' },
        ];
      
        // map: Transforms each element in the array
        const productNames = products.map((product) => product.name);
        const discountedPrices = products.map((product) => ({ ...product, price: product.price * 0.9 })); // 10% discount
      
        // filter: Creates a new array with elements that pass a condition
        const electronics = products.filter((product) => product.category === 'Electronics');
        const expensiveProducts = products.filter((product) => product.price > 100);
      
        // reduce: Combines all elements into a single value
        const totalPrice = products.reduce((accumulator, product) => accumulator + product.price, 0);
        const productSummary = products.reduce((summary, product) => `${summary}${product.name} (${product.category}) - $${product.price}\n`, "");
      
        // find: Returns the first element that satisfies a condition
        const bookCategory = products.find((product) => product.category === 'Books');
        const productOver1000 = products.find((product) => product.price > 1000);
      
        // some: Checks if at least one element satisfies a condition
        const hasElectronics = products.some((product) => product.category === 'Electronics');
        const hasCheapProduct = products.some((product) => product.price < 20);
      
        // every: Checks if all elements satisfy a condition
        const allElectronics = products.every((product) => product.category === 'Electronics');
        const allProductsAffordable = products.every((product) => product.price < 2000);
      
        return (
          <div>
            <h2>Data Manipulation Examples</h2>
            <p>Product Names: {JSON.stringify(productNames)}</p>
            <p>Discounted Prices: {JSON.stringify(discountedPrices)}</p>
            <p>Electronics: {JSON.stringify(electronics)}</p>
            <p>Expensive Products: {JSON.stringify(expensiveProducts)}</p>
            <p>Total Price: ${totalPrice}</p>
            <p>Product Summary: <pre>{productSummary}</pre></p> {/* Use <pre> for formatted text */}
            <p>Book Category: {JSON.stringify(bookCategory)}</p>
            <p>Product Over $1000: {JSON.stringify(productOver1000)}</p>
            <p>Has Electronics: {hasElectronics.toString()}</p>
            <p>Has Cheap Product: {hasCheapProduct.toString()}</p>
            <p>All Electronics: {allElectronics.toString()}</p>
            <p>All Products Affordable: {allProductsAffordable.toString()}</p>
          </div>
        );
      }
      
      export default DataManipulation;
  3. Explain:

    • How filter extracts specific items.

    • How map transforms an array.

    • How reduce combines elements

    • How find returns element


Activity 3: Arrow Functions

  1. Syntax:

    const add = (a, b) => a + b;
    const double = n => n * 2; // Single parameter doesn’t require parentheses
  2. React Integration:

    • Update the ArrowExample from earlier to use arrow functions:

      const ArrowExample = () => {
        const numbers = [1, 2, 3, 4];
        const squaredNumbers = numbers.map(num => num * num);
      
        return (
          <div>
            <h3>Squared Numbers</h3>
            <p>{squaredNumbers.join(", ")}</p>
          </div>
        );
      };
      
      export default ArrowExample;
  3. Best Practices:

    • Use arrow functions for short functions and callbacks.

    • Avoid them in event handlers when this is required.


Part Two: Asynchronous Programming

Lesson Objectives:

  • Understand and use callbacks.

  • Use promises effectively.

  • Refactor code using async/await.

  • Learn React-specific async programming practices.

Programming Activities for Part Two

Activity 1: Using Callbacks

  1. Example:

    const fetchData = (callback) => {
      setTimeout(() => {
        callback("Data fetched successfully");
      }, 2000);
    };
    
    const CallbackExample = () => {
      const buttonClick = () => {
        fetchData(message => {
          alert(message);
        });
      };
    
      return <button onClick={buttonClick}>Fetch Data</button>;
    };
    
    export default CallbackExample;
  2. Discuss:

    • How callbacks work.

    • Issues: Callback hell.


Activity 2: Promises (better Solution to Callback hell)

  1. Task:

    • Refactor the callback code using promises:

      const fetchData = () => {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve("Data fetched successfully");
          }, 2000);
        });
      };
      
      const PromiseExample = () => {
        const buttonClick = () => {
          fetchData().then(message => {
            alert(message);
          });
        };
      
        return <button onClick={buttonClick}>Fetch Data</button>;
      };
      
      export default PromiseExample;
  2. Explain:

    • How promises handle asynchronous tasks.

    • Benefits over callbacks.


Activity 3: Async/Await

  1. Refactor the Promises Example:

    const fetchData = async () => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("Data fetched successfully");
        }, 2000);
      });
    };
    
    const AsyncAwaitExample = () => {
      const buttonClick = async () => {
        const message = await fetchData();
        alert(message);
      };
    
      return <button onClick={buttonClick}>Fetch Data</button>;
    };
    
    export default AsyncAwaitExample;
  2. Benefits of Async/Await:

    • Cleaner syntax.

    • Avoids promise chaining.


Activity 4: Destructuring Assignment

The destructuring assignment syntax is an expression that makes it possible to unpack values from arrays or properties from objects. It's a very common and useful feature in modern JavaScript.

// Array destructuring:
const numbers = [1, 2, 3];

// Traditional way:
const first = numbers[0]; // first = 1
const second = numbers[1]; // second = 2
const third = numbers[2];  // third = 3

// With destructuring:
const [a, b, c] = numbers; // a = 1, b = 2, c = 3

// Skipping elements:
const [, , d] = numbers; // d = 3 (skips the first two elements)

// Rest operator with ... (spread) operator:
const [e, ...rest] = numbers; // e = 1, rest = [2, 3]

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

// Traditional way:
const personName = person.name; // personName = "Alice"
const personAge = person.age;   // personAge = 30

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

// Renaming properties:
const { name: userName, age: userAge } = person; // userName = "Alice", userAge = 30

// Default values:
const { country = "USA" } = person; // country = "USA" (since 'country' is not in the object)

// Nested object destructuring:
const student = {
    info: {
        name: "Bob",
        age: 20
    }
};

const { info: { name: studentName } } = student; // studentName = "Bob"


// Combined array and object destructuring:
const data = [
    { id: 1, name: "Product A" },
    { id: 2, name: "Product B" }
];

const [{ name: productName1 }, { name: productName2 }] = data; // productName1 = "Product A", productName2 = "Product B"

console.log(a, b, c);
console.log(d);
console.log(e, rest);
console.log(name, age, city);
console.log(userName, userAge);
console.log(country);
console.log(studentName);
console.log(productName1, productName2);

Anatomy of main.jsx

  • open Chrome Developer Tools (by CTRL+SHIFT+I (or F12 key) and open Console to explore console log output.

  • Console › {type: 'h1', key: null, props: {children: 'Hello from createElement!'}, _owner: null, _store: {}}

// main.jsx

import { createElement } from "react"
import { createRoot } from "react-dom/client"
//import ReactDom from 'react-dom/client'

const root = createRoot(document.getElementById("root"))
const reactElement = createElement("h1", null, "Hello from createElement!")

console.log(reactElement)

root.render(
    reactElement
)

Key Takeaways for Students

  • Modern JavaScript features, such as arrow functions, anonymous functions, and array methods, are essential for writing React components effectively.

  • Master asynchronous programming techniques, as React often involves handling async tasks (e.g., API calls).

  • Refactor code for clarity and maintainability, using async/await when possible.

Why React?

Lego Bricks Block Build

Vanilla JavaScrpt vs React

// index.html
<html>
    <body>
        <div id="app">
            <script type="text/javascript">
                
                const app = document.getElementById('app');

                // creates a new h1 element
                const header = document.createElement('h1');

                // create a new text node for the h1 element
                const headerContent = document.createTextNode(
                'This is my web application!');

                // append the text to the h1 element
                header.appendChild(headerContent);

                // place the h1 element inside the div
                app.appendChild(header);
            </script>
        </div>
    </body>
</html>
// index.html - react
<html>
    <body>
        <div id="app"></div>
            <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
            <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
            <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
            <script type="text/jsx">
                const app = document.getElementById('app');
                ReactDOM.render(<h1>This is our web App!</h1>, app);
            </script>
    </body>
</html>

React's popularity stems from a combination of factors that make it a compelling choice for web development:

  • Component-Based Architecture: This promotes code reusability, organization, and maintainability, especially in large applications.

  • Virtual DOM: This enhances performance by minimizing direct manipulations to the actual DOM, leading to faster rendering and smoother user experiences.

  • Large and Active Community: This provides ample resources, libraries, and support for developers.

  • JSX: This syntax extension allows developers to write HTML-like code within JavaScript, making UI development more intuitive. It allows to create easily reusable and interchangeable "pieces of of the web" that can be combined in various ways to create complex systems

  • Strong Focus on UI: React excels at building interactive and dynamic user interfaces.

  • Declarative Programming : Focuses on what the program should do, and describes the desired outcome without specifying how to achieve it.

In short, React offers a powerful, efficient, and developer-friendly way to build modern web applications.

PreviousLesson 3 - CSS ReviewNextLesson 5 - Set up Dev Environment

Last updated 3 months ago