Haaga-Helia Front End Programming Course

website·Indexed 30 days ago

https://haagahelia.github.io/frontendprogramming/

Course documentation for front end programming, focusing on React, TypeScript, and modern web development. Covers functional components, state management, networking with fetch and GraphQL, testing with Vitest, and integrating third-party libraries like MUI, React Router, and Tanstack Query.

Tokens
19.2K
Snippets
126
Records
143
Agent score
73%

What's inside Haaga-Helia Front End Programming

  1. Introduction to GraphQL queries

    GraphQL is a query language for APIs and a server-side runtime. Unlike REST APIs which use multiple endpoints, GraphQL typically uses a single endpoint. It allows clients to request exactly the data they need by specifying fields in a schema. Queries can also accept arguments (e.g., filtering by an ID) to refine the requested data.
    # Example: Querying a user by ID
    {
      user(id: 1) {
        username,
        email,
        phone
      }
    }
  2. Understand React components and their role in UI development

    React is a JavaScript library for building user interfaces using a declarative approach. The core building blocks of a React UI are components, which are reusable JavaScript functions. Components act like modular blocks (similar to Lego) that can be combined to construct a complete user interface.
  3. Manage shared state using the React Context API

    The Context API allows you to share state across multiple components without passing props manually through every level of the component tree (prop drilling). It is ideal for global data such as user authentication, themes, or preferred language settings.
  4. Use the useEffect hook for side effects

    The useEffect hook allows you to perform side effects (such as network requests) in React function components. It takes two arguments: a callback function containing the side-effect code and an optional dependency array.
    React.useEffect(callback, [dependencies])
  5. Consume Context values with the useContext hook

    Any component nested within a Context Provider can access the shared state by calling the useContext hook and passing the context object as the argument.
    import { useContext } from 'react';
    import ThemeContext from './ThemeContext';
    
    const MyComponent = () => {
      // Access the value provided by the ThemeProvider
      const { theme, toggleTheme } = useContext(ThemeContext);
    
      return (
        <>
          <button onClick={toggleTheme}>Change theme</button>
          <p>Current theme is: {theme}</p>
        </>
      );
    };
    
    export default MyComponent;
  6. Clean up side effects in useEffect

    To prevent memory leaks or unwanted behavior when a component is removed from the page (unmounted), you can return a cleanup function from the useEffect callback. This returned function is invoked when the component unmounts.
    import { useEffect } from 'react';
    import { createConnection } from './chat.js';
    
    function ChatRoom() {
      useEffect(() => {
        const connection = createConnection('https://localhost:1234/room1');
        connection.connect();
    
        // Cleanup function: invoked when component is unmounted
        return () => {
            connection.disconnect();
        };
      }, []);
      
      return <div>Chat Room</div>;
    }
  7. Use named exports to export multiple identifiers

    Named exports allow a module to export multiple variables, functions, or classes. You can either add the export keyword directly in front of the declaration or list all exports in a single statement at the end of the file. When importing named exports, you must use curly braces {}. Imported variables are always treated as constants.
    // mylib.js
    export const myPi = 3.14;
    export function circleArea(r) {
      return myPi * r * r;
    }
    
    // Alternatively, at the end of the file:
    // export { myPi, circleArea };
    
    // Importing in another file:
    import { myPi, circleArea } from './mylib.js';
    console.log(myPi);
  8. Implement nested routes and layouts with Outlet

    Use the Outlet component within a parent route's element to act as a placeholder for nested child routes. Child routes are defined in the children array of a parent route object. An index: true route is rendered when the parent's path is matched exactly. Use the Link component for navigation to avoid full page reloads.
    // App.tsx (Parent Layout)
    import { Link, Outlet } from 'react-router';
    
    function App() {
      return (
        <>
          <nav>
            <Link to="/">Home</Link>
            <Link to="/about">About</Link>
          </nav>
          <Outlet />
        </>
      );
    }
    
    // main.tsx (Route Configuration)
    const router = createBrowserRouter([
      {
        path: "/",
        element: <App />,
        children: [
          {
            index: true, // Renders at / 
            element: <Home />,
          },
          {
            path: "about", // Renders at /about
            element: <About />,
          },
        ]
      }
    ]);
  9. Declare and inherit classes in ES6

    Use the class keyword to define a class. The constructor method is used to initialize object properties when a new instance is created. Inheritance is achieved using the extends keyword, and the super() method must be called in the subclass constructor to initialize the parent class.
    class Shape {
      constructor (id, x, y) {
        this.id = id
        this.move(x, y)
      }
      move (x, y) {
        this.x = x
        this.y = y
      }
    }
    
    class Circle extends Shape {
      constructor (id, x, y, radius) {
        super(id, x, y)
        this.radius = radius
      }
    }
  10. Test React component interactions with Vitest and React Testing Library

    To test React components, use render from @testing-library/react to mount the component and screen to locate elements. Use fireEvent to simulate user interactions like changing input values or clicking buttons. To ensure test isolation and prevent components from persisting between tests, use the cleanup function within Vitest's afterEach hook. For assertions on the DOM, import @testing-library/jest-dom/vitest to enable matchers like toHaveTextContent.
    import TodoList from "./TodoList";
    import { test, afterEach, expect } from "vitest";
    import { render, screen, cleanup, fireEvent } from "@testing-library/react";
    import '@testing-library/jest-dom/vitest';
    
    afterEach(() => {
      cleanup();
    });
    
    test("add todo", () => {
      render(<TodoList />);
    
      // Find input by placeholder and simulate change
      const desc = screen.getByPlaceholderText("Description");
      fireEvent.change(desc, { target: { value: "Go to coffee" } });
    
      const date = screen.getByPlaceholderText("Date");
      fireEvent.change(date, { target: { value: "20.11.2025" } });
      
      // Find button by text and simulate click
      const button = screen.getByText("Add");
      fireEvent.click(button);
    
      // Assert that the table contains the added text
      expect(screen.getByRole("table")).toHaveTextContent(/go to coffee/i);
    });