Web Deployment Checklist: Release and Roll Back a Course App

Practical Web Development — Lesson 10 of 10 · Senior A successful deployment command does not prove a course application works. A release is complete when important user journeys work in the target environment and the team can recognize and recover from a bad change. This lesson turns a small course app into a practical release exercise with explicit acceptance and rollback criteria. Describe the change and its risk Suppose a release adds saved course shortlists. Separate the new browser interface, the server endpoint and any database change. Identify what happens when old browser code talks to the new server, and when the previous server version reads newly written data. Rolling back code is not the same as reversing a data migration. Write a short release record before deploying. Use real commit and build identifiers in your own project; the values below are placeholders for the exercise. Change: Add saved course shortlists Build: <immutable build identifier> Owner: <person ...

React State Tutorial: Build a Course Filter

Web Development Learning Series — Part 6 of 10 · Intermediate to Advanced

React is useful when a page has several connected interactive views. The challenge is often deciding what the application needs to remember. This lesson builds a difficulty filter for a course catalog and keeps the state small.

Use an existing React learning project or the official documentation's interactive editor. This example is a component, not a complete installation guide. You should already know JavaScript arrays, functions, and basic JSX.

Write the behavior first

The reader chooses all levels or one difficulty. The list updates immediately. An empty result shows a helpful message. Course data comes through props and remains unchanged by filtering. There is no network request in this example.

The selected level needs state because a visitor can change it. The filtered array does not need separate state because it can be calculated from the selected level and the course data.

A small working component

import { useState } from 'react';

function CourseCard({ course }) {
  return <li>
    <h2>{course.title}</h2>
    <p>Level: {course.level}</p>
  </li>;
}

export default function CourseCatalog({ courses = [] }) {
  const [level, setLevel] = useState('all');
  const visible = level === 'all'
    ? courses
    : courses.filter(course => course.level === level);

  return <section aria-labelledby="catalog-title">
    <h1 id="catalog-title">Course catalog</h1>
    <label htmlFor="level">Difficulty</label>
    <select id="level" value={level}
      onChange={event => setLevel(event.target.value)}>
      <option value="all">All levels</option>
      <option value="beginner">Beginner</option>
      <option value="advanced">Advanced</option>
    </select>
    <p role="status">{visible.length} courses found</p>
    {visible.length === 0
      ? <p>No courses at this level yet.</p>
      : <ul>{visible.map(course =>
          <CourseCard key={course.id} course={course} />
        )}</ul>}
  </section>;
}

Render it from a parent with sample data such as the following. Keep course identifiers stable if the list can be reordered or updated.

const courses = [
  { id: 'html', title: 'HTML Foundations', level: 'beginner' },
  { id: 'architecture', title: 'Web Architecture', level: 'advanced' }
];
// In the parent component's returned JSX:
// <CourseCatalog courses={courses} />

Avoid synchronizing duplicate information

If you store both level and visible courses, every change to the data or selection must update both correctly. That introduces a coordination problem. Deriving visible results during rendering avoids that problem for this small catalog.

You do not need an effect just to filter an array. Effects are appropriate for synchronizing with external systems, and should be considered separately from calculations needed to describe the current view. Do not add memoization to a tiny list before measuring a real performance concern.

Choose component boundaries for a reason

CourseCard groups the content for one record. The catalog owns selection because it coordinates the control and results. If another view later uses that selection, move ownership to their nearest useful shared parent. Do not put every input into global state merely because a state library is available.

Check the user journey

Use the keyboard to change the select. Confirm that the count changes and the correct cards remain. Pass an empty array, reorder the data, and add a course with a long title. Verify that a reader can distinguish “no matching courses” from an API load failure if you later introduce fetching.

Practice task

Add a search field and derive results from both controls. Then add intermediate courses. Decide whether clearing the search should reset the selected difficulty or leave it in place, and make the behavior predictable.

Continue your learning

Previous lesson: TypeScript for JavaScript Developers: Validate Data at the Boundary. Explore our web development series and the HTML multimedia project.

Reference: Official documentation for this lesson. Examples are learning exercises; adapt and test them for your own application.

Comments

Popular posts from this blog

What Is Multimedia? Examples and a Beginner Course Guide

Internet vs World Wide Web: HTML and Multimedia Explained

VR vs AR: Differences, Uses and Multimedia Design