Loading the Lineup

Loading data is a job for an effect, too. The app should ask the server for the lineup once, when it appears, so the effect has the dependencies []. The bands are in the file bands.json, and you load them with fetch(), as in the JavaScript course:

useEffect(() => {
    async function loadBands() {
        const response = await fetch("bands.json");
        setBands(await response.json());
    }
    loadBands();
}, []);

Why the function inside? fetch() needs await, and await works only in an async function. But the function you give useEffect can't be async itself: an async function always returns a Promise, and React expects an effect to return nothing or a cleanup. So the effect makes an async function and calls it straight away.

The first render shows an empty list, because bands starts as []. A moment later, the data arrives, setBands() changes the state, and React renders the list with the bands. The effect doesn't run again: its dependencies haven't changed.

While the user waits, the page should say so, and when the server answers with an error, it should say that too. Both are just more state: loading, which is true until the answer comes, and error, with the text of an error message, or "" when there's none. The page shows each of them with &&:

{loading && <p>Loading…</p>}
{error !== "" && <p className="error">{error}</p>}

And remember response.ok from the JavaScript course: it's false when the server answered with an error, such as 404 Not Found for a misspelled file name.

A typical mistake is to call fetch() right in the component, without an effect. Then every render loads the data again, the data changes the state, the new state renders again… and the app asks the server again and again, without end.

Instructions

Add an effect with the dependencies [] that loads bands.json and puts the bands into bands with setBands(). Then the list shows all five bands.

Add a state variable loading, true at first, and set it to false after setBands(). While it's true, show <p>Loading…</p> above the list.

If the response isn't OK, set loading to false, put The lineup couldn't be loaded. into a state variable error ("" at first), and end the function with return. Show the error in <p className="error"> above the list. Try it: misspell the file name in fetch(), and then fix it again.

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

Back

5/9

Next