
Quick Lecture Overview
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
##Looks like we found a thief monkey By the way, I liked the trick how you reached till here. You have a good sense of humor. You will improve a lot if you join our course with this passion.
var
(function-scoped, outdated)let
(block-scoped, modern and recommended)const
(block-scoped, cannot be reassigned)_
, or $
let let = 5;
is invalid)myVar
and myvar
are different)string
, number
, boolean
, null
, undefined
, bigint
, symbol
Objects
, Arrays
, Functions
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
00:00:02 In this lesson, I'll teach you how you can fetch external data, which if you're learning React for the first time, will open up a world of possibilities.
00:00:11 That's because there are hundreds, no, thousands of different APIs that you can call directly from your application to get super unique data to build an
00:00:21 application about anything.
00:00:23 If you're a fan of anime, you can do that.
00:00:25 Fan of anti-malware, you can do that too.
00:00:28 Art and design, authentication, blockchain, books, I mean, you name it.
00:00:33 There is an endless list of APIs that you can use to power up your React applications.
00:00:39 And when I was first learning React many, many years ago, when I learned how I can fetch this external data, it opened up the world of possibilities.
00:00:48 For this course, I chose the Movie Database API as we all watch movies, right?
00:00:54 And it's free to use.
00:00:55 So just Google for TMDB, head over to API Reference, and then search for movie.
00:01:02 We want to head over to Discover Movie.
00:01:05 Here, you can see all the information on how we can make a request to this API, but I believe first we have to create an account to get our API key.
00:01:15 So let's go ahead and log in at the top right.
00:01:17 You can create an account by clicking right here, enter a few pieces of info, and once you're in, you can head over to More,
00:01:24 API, and this will bring us back to the page we were on.
00:01:27 Head over to API Reference, and search for movie discover.
00:01:33 And this time you'll have your own access token.
00:01:35 So let's go ahead and copy it by selecting it from here and let's paste it into our application.
00:01:42 Now in React apps, you never want to have your key right here by saying something like TMDB API key is equal to a string.
00:01:50 because then everyone will be able to have access to it.
00:01:53 What you want to do instead is put it under environment variables.
00:01:57 So let's delete this and let's create a new file in the root of your folder and call it .env.local.
00:02:07 Again, make sure that it is not outside of your main application folder, like right here.
00:02:13 It should be where your source is.
00:02:15 So right next to it.
00:02:16 And then you need to start your key with the keyword VEAT underscore TMDB underscore API underscore key and simply paste your key right here.
00:02:27 Now you may need to restart your terminal for the changes to take effect and for this variable to be recognized.
00:02:34 So head over to your first terminal, press Ctrl C to stop it from running, and then run npm rundev one more time to spin it up on localhost 5173. Once
00:02:44 you do that, what do you think?
00:02:45 Which React hook do we need to use to fetch the movies?
00:02:50 It's useEffect.
00:02:51 So let's import it right here at the top.
00:02:55 Import useEffect from React.
00:02:57 and then below this useState, let's create it.
00:03:01 useEffect, which will only load at the start.
00:03:05 How do we do that?
00:03:06 Well, we provided an empty dependency array.
00:03:10 Only run this once this component loads.
00:03:12 Now, how can we actually fetch this data from the API?
00:03:15 I mean, we have the key, but what do we do with it?
00:03:18 Well, to know the answer to that question, you'll have to read through the docs a bit.
00:03:22 Documentation is the most important part of learning how to code.
00:03:26 And immediately at the top, we get the exact API endpoint that we need to call.
00:03:31 API refers to an application programming interface.
00:03:36 And it is simply a set of rules that allows one software application, in this case, a React app, to talk to another, which is a database or server set
00:03:46 somewhere else.
00:03:46 In this case, we're using TMDB's API to get a list of movies.
00:03:50 So we have to send over a request that says something like, hey, give me a list of your most popular movies.
00:03:57 We can do that by first defining the API base URL, which will be equal to HTTPS We do have something after that, but we'll specifically craft that part later.
00:04:18 For now, we just want to have the base part of the URL.
00:04:21 After that, we can also get access to our API key by saying const API underscore key.
00:04:28 And typically when you're naming your variables and you know they're not going to change, you can use this kind of case where we have all uppercase letters
00:04:36 and then underscores.
00:04:38 And here we can get the variable by saying import.meta.env.vit tmdb API key.
00:04:48 Make sure to spell this correctly.
00:04:49 This variable name right here needs to be the same as here.
00:04:53 After that, we have to define the API options by saying const API options is equal to we can define the method as get.
00:05:04 So we want to get some movies.
00:05:06 And then we can define the headers, which is an object where we can say accept, and you can define what kind of data do we accept in our application.
00:05:16 And it'll be an application JSON, which means that the API will send back a JSON object, which is similar to a basic JavaScript object with some minor differences.
00:05:26 And we have to authenticate the API by saying authorization and then say bearer and then pass the API key.
00:05:34 This verifies who is trying to make that request.
00:05:37 In this case, we created an account on their API so we can do that.
00:05:41 And we're finally ready to declare a function that allow us to fetch those movies.
00:05:47 So let's do it above the use effect by calling it const fetchMovies is equal to an asynchronous function that'll look something like this.
00:05:57 Within it, when you're fetching something, typically it's a good practice to open up a try and catch block.
00:06:04 If something fails with the API call, then you get into the catch where you have access to the error.
00:06:11 So then you can console that error the error.
00:06:14 And we can also say something like error fetching movies.
00:06:19 Like this.
00:06:21 And this way we're getting a bit more information about a specific error that happened.
00:06:25 Now a pretty cool thing is that we can also display that error in the browser.
00:06:30 React makes it super simple.
00:06:32 We can do that by declaring a new state.
00:06:35 So let's say use state and let's call it error message.
00:06:41 Set error message at the start equal to null.
00:06:45 or an empty string, because we don't have any message in there.
00:06:48 But now, if we catch an error, we can set error message to a meaningful message.
00:06:54 Something like, error fetching movies, please try again later.
00:06:58 And now, where do we display that message?
00:07:01 Well, wherever you want.
00:07:03 We can create a new section right here below our search.
00:07:07 As a matter of fact, let's put the search within the header, and then we can declare this new section about movies below the header.
00:07:14 So it'll be section.
00:07:16 And we can have a class name of AllMovies.
00:07:21 And we can render an H2 that'll say AllMovies.
00:07:27 There we go.
00:07:28 Now, what you can do is say, if there's an error message, render a p tag with something like text-red500 and then display that error message.
00:07:39 We'll actually explore that in practice very soon, but for now we have to keep trying to call the API.
00:07:45 We're not even successfully calling it yet.
00:07:47 So now let's move into the try block where we can try to call it.
00:07:52 And first things first, we need to define the exact endpoint that we're trying to call.
00:07:57 And the endpoint will be equal to a template string, where we put together the API base URL, and then we go to forward slash,
00:08:07 discover, forward slash movie question mark sort by equal to popularity dot D E S C for descending.
00:08:20 So this will make sure to fetch all the movies.
00:08:23 Once we have the end point, we can try to call it by saying constant response is equal to a weight fetch.
00:08:32 to which we pass the endpoint and API options.
00:08:35 Now see this fetch over here?
00:08:38 This is a built-in JavaScript function that allows you to make HTTP requests, like get or post to different APIs or servers.
00:08:46 It's like sending a letter to a service and getting a reply.
00:08:49 In React, fetch is often used to get the data from APIs for displaying it on the website.
00:08:55 So how do we actually put this fetch movies to practice?
00:08:58 Because right now it is completely unused.
00:09:01 What do you think?
00:09:03 Well, we can simply call it as soon as the app loads.
00:09:06 So if I call it within the use effect, like this, what do you think?
00:09:12 Will it work?
00:09:14 Fetch movies, no errors, right?
00:09:17 Which is a good thing.
00:09:18 Maybe we can put an alert and just alert the response.
00:09:22 Yeah, that works.
00:09:23 We get some kind of an object back.
00:09:25 That's great.
00:09:26 But what would happen if something went wrong?
00:09:29 For example, if an error happened here, like we can throw a new error, say, failed to fetch movies, just to simulate a wrong call.
00:09:38 If I do this, you can immediately see, error fetching movies, please try again, error message happening at the bottom.
00:09:45 no reload, no nothing, it's just immediately there.
00:09:48 But thankfully, we don't get it if we don't manually throw it, which means that we do get back some data.
00:09:55 So let's actually parse this response into a JSON object by saying, if not response.ok, well, in that case, we might want to throw some kind of an error
00:10:06 saying fail to fetch movies.
00:10:08 But if the response is okay, we can get data by saying cons data is equal to await response.json.
00:10:17 And finally, we can console log that data to see what do we have in there.
00:10:21 If I reload the application and head over to inspect and then open up our console, you can see that we get back only one object.
00:10:30 Doesn't seem like a lot, does it?
00:10:32 But if I expand it, we only get back the first page which has 20 movies in it.
00:10:38 I'll need to expand it to view it more properly.
00:10:41 There we go.
00:10:42 These are only 20 movies.
00:10:44 And for each one of these movies, take a look at how much data do we get.
00:10:48 We get an image of that movie, the ID, the original language, title, overview, popularity, poster path, release date, title,
00:10:58 video, vote average, vote count, and more.
00:11:01 And we get this for every single movie.
00:11:04 And this is just the first page.
00:11:06 But take a look.
00:11:07 we have 48,000 total pages, which is almost a million movies.
00:11:13 Pretty crazy, isn't it?
00:11:14 And now we can infuse our React application with all that data and show it to the user.
00:11:20 So let's do just that.
00:11:21 I'll say if data.response is equal to false, then I'll set the error message equal to data.error, or fail to fetch movies.
00:11:33 Sometimes something wrong can happen, we have to handle that error.
00:11:37 And in this case, it will also be a good time to create a state field, like an empty box, inside of which we can place all of these movies that we fetched.
00:11:45 So let's create it right here at the top.
00:11:47 I'll call it useState.
00:11:51 And I'll call it movie list, or we can simply call it movies, it's up to you.
00:11:57 Set movie list at the start equal to an empty array.
00:12:01 Another state we'll have to have, and we often have those in React applications.
00:12:06 is the loading state so we can call it is loading set is loading at the start set defaults because when you're fetching something from an API it takes
00:12:16 time maybe a second or two so while that data is loading you want to make sure to show some kind of a loader to the user so we're still here in the case
00:12:24 if it fails If it fails, we simply want to set the movie list to be equal to an empty array and we want to return, meaning exit out of the function.
00:12:33 But if it succeeds, then we are ready to set movie list to be equal to data.results or an empty array.
00:12:42 So this will actually finally populate the movie list with real movies.
00:12:47 Another thing we have to do is turn on the loading.
00:12:50 So before anything happens, right at the start, we can set isLoading to true to start the countdown.
00:12:59 And we can also set error message to nothing because it doesn't exist yet.
00:13:05 And then, there's another clause to the try and catch, and that is the finally clause.
00:13:11 So finally, no matter what happens, whether we succeed or fail, we want to stop the loading.
00:13:17 Why?
00:13:17 Because if we succeed, we'll show the movies.
00:13:20 If we fail, we'll show the error message.
00:13:22 No need to show the loading state.
00:13:24 With that in mind, Now that we have this function that fetches all the movies, called fetchMovies, we're calling it at the start,
00:13:31 we're finally ready to use the data that the fetchMovies populated into our movie list state.
00:13:38 So let's head down a bit, and right below all movies, let me show you a bit more complex conditional rendering.
00:13:45 We won't show this error message always.
00:13:48 Rather, first, we'll check if we're currently loading.
00:13:52 So if isLoading, then open up EternaryOperator and show a p tag of loading...
00:14:00 Maybe we can also give it a class name equal to text-white.
00:14:06 Else, if you're not loading, check if an error message exists.
00:14:11 And if an error message exists, then render another p tag that'll have a class name equal to text-red-500 and it'll render the dynamic error message coming
00:14:25 from the state.
00:14:25 And if we're neither loading nor showing the error message, then we want to show an unordered list, a UL element, inside of which we're going to map over
00:14:37 the movie list by saying movielist.map, By the way, this is something you often do in React whenever you have some kind of an array of items you want to
00:14:46 map over.
00:14:46 You simply call that array, call the .map method on it, get the individual element like a movie from it, and then automatically render something.
00:14:56 Now make sure not to open up a function block here by putting the curly braces instead put parentheses because if you put curly braces which is totally
00:15:07 okay but then you would also have to say return here but if you use just immediate return by using parentheses then you don't have to say return making
00:15:16 your code a bit cleaner.
00:15:17 For each one of these movies return a p tag that'll render a movie title and now if i save this so if i save this it seems that nothing happened but if
00:15:29 i apply a class name to this p tag equal to text-white check this out we get 20 of the most popular movies at this exact point in time for you this list
00:15:42 will be different from me because some other movies are trending.
00:15:46 And that's the beauty of calling APIs.
00:15:48 You don't have to worry about the data.
00:15:50 Somebody else is doing that for you.
00:15:52 Now, another important concept in React is a concept of a key.
00:15:57 Whenever you're mapping over a list of elements, you want to make sure to provide a key to each one of these elements you're mapping over.
00:16:05 that key has to be unique, something like an ID, so we can simply pass the ID belonging to this movie.
00:16:11 This is needed especially if you're deleting some of these elements from the list, because React then might confuse the two elements together and be not
00:16:19 sure what to render.
00:16:20 But if you give each one an ID, then it'll always know which one it is, and you'll have no unexpected behavior in your browser.
00:16:28 Great.
00:16:28 With that in mind, let's check how these movies are loading.
00:16:31 Like if I reload right now, oh, they're already stored in memory, so it's super quick.
00:16:37 But for a brief second, you should be able to see loading right here.
00:16:40 For now, we can simulate it by heading over to our state and turning the isLoading initially to be set to true.
00:16:48 And then under fetch movies, if you head over to the bottom, in the finally clause, you can also set it to true.
00:16:56 And now you can see a loading.
00:16:58 But this is not looking that interesting, is it?
00:17:01 It would be better to have some kind of a real spinner that looks like this.
00:17:04 There are many different spinners online, people offer them for free, they work in different light or dark modes, and you can simply copy the code.
00:17:12 I'll put the link to this website in the description so you can find your spinner of choice and just copy the clipboard.
00:17:19 Then we'll create a new component by heading over to source, components, and let's call it spinner.jsx.
00:17:29 Run RAFCE.
00:17:32 And instead of this div right here, simply paste the code that you just copied.
00:17:37 It'll be a bit of a longer code because it's an SVG, but that's okay.
00:17:41 And at the end of this class name, instead of fillBlue600, change it to fillIndigo600.
00:17:48 I think this color pops a bit more on our background or any color of your choice.
00:17:53 Now, if you head back over to our app.jsx, Instead of simply returning a loading text, if it's loading, we can return a new component,
00:18:05 which we can import from the components folder, and it'll look something like this.
00:18:09 Much better, right?
00:18:11 Now we can bring this back to false.
00:18:13 And same thing right here at the top, initially.
00:18:17 Great.
00:18:17 Also, let's quickly give this H2 a class name of margin top of something like 20 pixels.
00:18:26 And we can do that within square brackets like this.
00:18:30 There we go.
00:18:31 I think maybe even 40 will do.
00:18:33 Perfect.
00:18:34 With that in mind, now we have a fully responsive, great-looking list of movie names or movie titles, but not movie cards.
00:18:44 One thing I love the most about all of these APIs is when they're visual.
00:18:49 People are visual beings, and seeing something that looks like this with a lot of movie covers, ratings, and more is much better than just seeing the titles themselves.
00:18:59 And we'll do that next.
00:19:01 But it's not that hard, is it?
00:19:03 Once you understand something at its core, it won't feel tricky the next time.
00:19:07 And that's why before, in the crash course, I went into detail about how useEffect works, and I showed you how to implement it.
00:19:15 So this time you fully understand how it does and you'll be able to replicate it in all of your apps in the future.
00:19:21 But that's just one hook and there are many more in React 19. Like use action state is one of these hooks.
00:19:29 Use optimistic.
00:19:31 Use form status, and I also think there's a use transition.
00:19:35 Yep, that's here too.
00:19:37 And each one of them comes with its own quirks.
00:19:39 I'll cover each one of these in depth along with their specific use cases in my upcoming pro course.
00:19:46 So if you want to go beyond what most people learn, be sure to check it out.
00:19:50 The link is in the description.
00:19:51 There's either going to be a wait list or if you're lucky, the course will already be there.
00:19:57 With that in mind, let's turn this.
00:20:00 into this.