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
  • Building the Meme Generator Application
  • Step 1: Project Setup
  • Step 2: Implement App.jsx
  • Step 3: Implement Header.jsx
  • High Level Overview on Functional Programming
  • Step 4: Implement MainMeme.jsx
  • Step 5: Add Styling
  • Step 6: Run the Application

Solo Project 1

PreviousHands-on :Use Dependency Array and Adding Values that Control Side EffectsNextRESTful APIs :Build a BookSearch App -Ver 2.0

Last updated 1 month ago

Building the Meme Generator Application

This guide will walk you through building a Meme Generator Application using React. We will structure our project with a parent component (App.jsx) and two child components (Header.jsx and MainMeme.jsx). Styling will be implemented using the Bootstrap package.

Step 1: Project Setup

  1. Initialize the React Project:

    npm create vite@latest
    >react-scrimba-meme-app
    >React
    >JavaScript
    
    cd meme-generator
  2. Open code . and open terminal. Then Install Bootstrap:

    npm install bootstrap

    Add the following import to src/index.css to include Bootstrap:

    import 'bootstrap/dist/css/bootstrap.min.css';
  3. Project Structure: Create a components folder inside the src directory to house Header.jsx and MainMeme.jsx.

Step 2: Implement App.jsx

The App.jsx component will act as the parent component.

  • import bootstrap package :

    import 'bootstrap/dist/css/bootstrap.min.css'
import React from 'react';
import Header from './components/Header';
import MainMeme from './components/MainMeme';
import 'bootstrap/dist/css/bootstrap.min.css'

function App() {
  return (
    <div>
      <Header />
      <MainMeme />
    </div>
  );
}

export default App;

Step 3: Implement Header.jsx

The Header.jsx component contains a header with an icon on the left and a title on the right.

import React from 'react';
import './Header.css'; // Optional: Create this file for additional custom styles.

function Header() {
  return (
    <header className="d-flex justify-content-between align-items-center bg-primary text-white p-3">
      <img src="https://via.placeholder.com/40" alt="Meme icon" className="rounded-circle" />
      <h1 className="m-0 text-center">Meme Generator</h1>
    </header>
  );
}

export default Header;

High Level Overview on Functional Programming

The image highlights three core principles of functional programming: Pure Functions, Immutability, and Avoiding Side Effects. These principles are highly relevant to React development and contribute significantly to building predictable, testable, and maintainable components. Let's explore how they apply in the context of React:

Functional Programming Overview in React

Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. 1 In React, this translates to writing components as pure functions that receive data (props) and return a UI representation (JSX).

1. Pure Functions

  • Definition: A pure function always returns the same output for the same input and has no side effects.

  • In React: React components can be written as pure functions. They receive props as input and return JSX as output. The output depends solely on the input props.

    JavaScript(JSX)

    // Pure function component
    function MyComponent(props) {
      return <div>Hello, {props.name}!</div>;
    }
  • Benefits:

    • Predictability: Given the same props, the component will always render the same output.

    • Testability: Easier to test because the output is predictable and doesn't depend on external factors.

    • Performance optimization: React can optimize rendering by memoizing pure components.

2. Immutability

  • Definition: Immutability means that once an object is created, its state cannot be changed. Instead of modifying an existing object, you create a new object with the desired changes.

  • In React: It's crucial to treat component state as immutable. Use methods like setState (in class components) or the state updater function returned by useState (in functional components with hooks) to create new state objects instead of directly modifying the existing state.

    JavaScript

    import React, { useState } from 'react';
    
    function MyComponent() {
      const [user, setUser] = useState({ name: 'Alice' });
    
      const updateName = () => {
        // Correct: Create a new object
        setUser({ ...user, name: 'Bob' });
    
        // Incorrect: Directly mutating the state (Avoid this)
        // user.name = 'Bob'; 
        // setUser(user);
      };
    
      return (
        <div>
          <p>Name: {user.name}</p>
          <button onClick={updateName}>Change Name</button>
        </div>
      );
    }
  • Benefits:

    • Predictable state changes: Easier to track how state changes over time.

    • Improved performance: React can perform efficient updates by comparing references of objects. If the reference is the same, React knows that the component doesn’t need to re-render.

    • Simplified debugging: Easier to reason about the flow of data and identify the source of bugs.

3. Avoiding Side Effects

  • Definition: A side effect is any operation that affects something outside the scope of the function being executed. Examples include making API calls, directly manipulating the DOM, using timers, or modifying global variables.

  • In React: Side effects should be managed within lifecycle methods (in class components) or using the useEffect hook (in functional components). This keeps side effects isolated and makes components more predictable.

    JavaScript

    import React, { useState, useEffect } from 'react';
    
    function MyComponent() {
      const [data, setData] = useState(null);
    
      useEffect(() => {
        // This is where you would perform side effects like fetching data
        fetch('/api/data')
          .then(res => res.json())
          .then(setData);
    
        // Cleanup function (important for avoiding memory leaks)
        return () => {
        // Any cleanup logic, like unsubscribing from timers or event listeners
        };
      }, []); // The empty dependency array ensures this runs only once on mount and unmount
    
      if (!data) {
        return <p>Loading...</p>;
      }
    
      return <p>Data: {data.value}</p>;
    }
  • Benefits:

    • Improved maintainability: Easier to understand and reason about the component's behavior.

    • Better testability: Easier to mock or control external dependencies during testing.

    • Reduced bugs: Minimizes unintended interactions between different parts of the application.

In summary: By adhering to the principles of functional programming, React developers can create components that are more predictable, easier to test, and simpler to maintain. This approach leads to more robust and scalable applications.

Step 4: Implement MainMeme.jsx

Meme Generator - Fetching Data from API

The MainMeme.jsx component handles the meme generation functionality. Refer to the provided MainMeme.jsx for layout configuration.

import React, { useState, useEffect } from 'react';
import './MainMeme.css';

export default function MainMeme() {
  const [meme, setMeme] = useState({
    topText: '',
    bottomText: '',
    randomImage: 'http://i.imgflip.com/1bij.jpg'
  });

  const [allMemes, setAllMemes] = useState([]);

  useEffect(() => {
    fetch("https://api.imgflip.com/get_memes")
      .then((response) => response.json())
      .then((data) => setAllMemes(data.data.memes));
  }, []);

  const handleChange = (event) => {
    const { name, value } = event.target;
    setMeme((prevMeme) => ({
      ...prevMeme,
      [name]: value
    }));
  };

  const getMemeImage = () => {
    const randomIndex = Math.floor(Math.random() * allMemes.length);
    const randomMeme = allMemes[randomIndex]?.url;
    if (randomMeme) {
      setMeme((prevMeme) => ({ ...prevMeme, randomImage: randomMeme }));
    }
  };

  return (
    <main className="container mt-5">
      <div className="form-group">
        <label htmlFor="topText">Top Text</label>
        <input
          type="text"
          className="form-control"
          id="topText"
          placeholder="Enter top text"
          name="topText"
          value={meme.topText}
          onChange={handleChange}
        />
      </div>

      <div className="form-group">
        <label htmlFor="bottomText">Bottom Text</label>
        <input
          type="text"
          className="form-control"
          id="bottomText"
          placeholder="Enter bottom text"
          name="bottomText"
          value={meme.bottomText}
          onChange={handleChange}
        />
      </div>

      <div className="meme mt-5 text-center">
        <button className="btn btn-primary mb-3" onClick={getMemeImage}>
          Get a new meme image 🖼
        </button>
        <div className="position-relative">
        <img src={meme.randomImage} className="img-fluid" alt="Meme" />
        <h2 className="top-text text-white position-absolute w-100 text-center">{meme.topText}</h2>
        <h2 className="bottom-text text-white position-absolute">{meme.bottomText}</h2>
      </div>
      </div>
    </main>
  );
}

Step 5: Add Styling

Create MainMeme.css to position the top and bottom text on the image:

.meme {
  position: relative;
  display: inline-block;
}

.top-text {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 24px;
  font-weight: bold;
  text-shadow: 2px 2px 4px black;
}

.bottom-text {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 24px;
  font-weight: bold;
  text-shadow: 2px 2px 4px black;
}

Step 6: Run the Application

  1. Start the application:

    npm run dev

Congratulations! You have built a functional meme generator app using React.

Open 5173 to see the Meme Generator in action.

http://localhost: