Loading the Showtimes

Now the showtimes page. The showtimes come from showtimes.json, as in the showtimes project, only now an effect loads them, as in the Effects lesson. They're state, an empty array at first, and the effect, with the dependencies [], loads the file when Showtimes appears:

const [showtimes, setShowtimes] = useState([]);

useEffect(() => {
    async function loadShowtimes() {
        const response = await fetch("showtimes.json");
        setShowtimes(await response.json());
    }
    loadShowtimes();
}, []);

In the table, map() makes a row for each showtime, with its id as the key: four cells with the day, the time, the film and the hall, and a fifth one with the Choose seats button. In the project The Cinema in Tailwind, the script gave that button its classes with button.className = "…". In JSX, you write them right on the button, as on any other element.

Each time you open the showtimes, Showtimes appears on the page again, so its effect runs again and loads the file again. When you go home, React takes the component off the page, and its state with it. That's fine here: the file is small, and the showtimes could have changed in the meantime.

While the file is on its way, the page says Loading…, and if the server answers with an error, it says so, as the old page did. That's two more pieces of state, loading and error, as in the Effects lesson. Check response.ok before you read the data.

Instructions

  1. In Showtimes.jsx, add the state showtimes and the effect from the example above (import useEffect and useState). In the tbody, show a row for each showtime, with its key: the cells with showtime.day, showtime.time, showtime.film and showtime.hall, and a cell with the button Choose seats, which gets the classes the script gave it: className="cursor-pointer rounded-full bg-night px-4 py-1 text-sm font-semibold text-white transition-colors hover:bg-night/80 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gold".

  2. Add the state loading, true at first, and set it to false once the showtimes are there. If response.ok is false, put The showtimes couldn't be loaded. into the state error ("" at first), set loading to false too and end the function with return. Under the paragraph, show <p className="mt-4">Loading…</p> while loading is true, and the error in <p className="mt-4 text-red-700"> when there is one. Try it: misspell the file name in fetch(), and then fix it again.