When it comes time to load external data from a server, we need a way to fit that into our component flow in a way that won't block rendering, or impact the user experience in a negative way. In React, we'll handle this with the useEffect hook. In this lesson, we'll use the useEffect hook to encapsulate a fetch call to a REST endpoint and talk about when it runs and how to prevent it from running on every render.
We'll remix this project from glitch for this lesson: https://glitch.com/~studydeck
Instructor: [0:00] To get started, we'll go to this URL on Glitch. We'll click "View Source." Then we'll click the "Remix to Edit" button in the top-right corner. This will create a new copy of the starter project that will provide our API for building this flashcard application.
[0:20] This project runs Server JS. Server JS expose a REST API that we can use for this application. It also stores its data locally in this JSON file. To get our unique URL, we'll just go up to share. We'll click on the "Live App" tab. We'll copy this URL. This will be the URL that we'll use to hit our copy of the REST endpoint for the rest of this course.
[0:43] It's probably not a bad idea to create an account and sign in so that you can get back to your project whenever you need to. Put the URL on your clipboard. Let's go into the code. I'm going to open up app.js.
[0:56] We'll start at the top of the app function, defining some state. I'm going to define a constant. This is going to be an array that I'm going to destructure. I'm going to use React.useState for this. This is going to be an array of cards. My setter function is going to be setCards. This will be a call to React.useState. My initial state for this is just going to be an empty array.
[1:21] Now we need to make our API call to populate these cards. I'm going to drop down. I'm going to make a call to React.useEffect. The useEffect hook is going to take a callback function that will run our effect. In this case, it's going to be our fetch call to get our card data.
[1:38] It's also going to take a dependencies array. If we don't provide this, this effect function will run on every single render. If we have data inside the useEffect that is important to the effect, we can set it so that it only runs when those dependencies change. If we only want it to run once, which is our case here, we pass it an empty array.
[2:00] Inside the body of this function is where we're going to make our API call. Inside this useEffect function, I'm going to use the fetch API. I'm going to paste in my URL from Glitch. I'm going to follow that up with /api/card. This is the endpoint that's going to give us back all of the cards in that data file.
[2:22] This will return a promise. I'll call .then. This is going to get our response. We want to take our response and get the JSON out of that. We'll chain on another then. This is where we're going to have our cards. This will be our cards array with an array of card objects. In here, I'm going to call my state updater function, setCards. I'm going to parse in that cards array from the API.
[2:51] Now I just want to see if this API call is returning the value and if that value is showing up on my state. I'm going to drop down here into where we're doing our render. Right before the cards UI, under the "Your Cards" heading, I'm just going to temporarily dump out the JSON data into the page so that we can see it in the browser.
[3:13] I'll just throw a pre tag in here. Then do a JSON.stringify. I'm going to pass that cards, null, and then a two for the spacing. We'll save this. In my terminal, I'm going to start this with yarn start.
[3:39] We can see after this has reloaded it made the API call. It grabbed all that JSON data from the file. It dumped it onto the page. Let's jump back into the code and do a tiny bit of refactoring.
[3:51] We're going to come in here. We'll leave this for now. I'm going to come back up to my useEffect call. We see here that then takes a callback function that accepts cards and then inside of it is just calling a function that passes in card.
[4:07] We basically are defining an anonymous function with the same signature as this function. Anytime you see this pattern, we can simplify this by just passing in a reference to that function directly.
[4:22] Now we can just say, "then setCards." We can save this. It'll rebuild. We'll go back to the browser. We can just verify that everything still works. We can see that it does.