Check out a free preview of the full React and TypeScript, v2 course
The "Fetching API Data Exercise" Lesson is part of the full, React and TypeScript, v2 course featured in this preview video. Here's what you'd learn in this lesson:
Students are instructed to replace the hard-coded state with data from the API and include the correct type for the array of quotes.
Transcript from the "Fetching API Data Exercise" Lesson
[00:00:00]
>> So the challenge I'm gonna give to you is I don't wanna show just one quote, I would like to show some number of quotes. Let's see, the fortune is false. If I put this part back in, We can see we get this fun form on the number of quotes to load.
[00:00:26]
And I wanna remove this one cuz they're all gonna show in here eventually, or we will put them in. In there, we can iterate through them. So the real UI I want is this fun form, That should load, where I can specify a number of quotes that I want and hit the endpoint that pulls in that many quotes, right?
[00:00:51]
And so this will be an array of quotes instead. So there'll be some differences in how this all plays out for us. But why don't you take it for a spin? And then we'll come back together and review some of the slightly variations on a theme that we get when we're dealing with an array versus just one value.
[00:01:13]
Okay, so the mission, whether or not you choose to accept it, was to swap out getting a single quote for getting multiple quotes. Now, for careful eagle eyes, there's a button for loading the quotes. So I don't need this useEffect anymore. Goodbye, useEffect. Nothing I like more than think about useEffect.
[00:01:36]
Also, very important technical change. [SOUND] There we go. And this is no longer valid. Now, one of the nice things I can do with collections, put an array. That works, right? Yeah, I'm setting you up, it works in JavaScript, it doesn't. Well, that one I'm getting yelled at because the quote doesn't exist anymore.
[00:02:08]
And I'm not using it, but if I tried to use it, I tried to use anything on it, right? So if I said quotes.map, and then I will grab the individual quote. I definitely shouldn't deleted that code earlier that had that, but we'll rewrite it. And we'll say return InspirationalQuote.
[00:02:29]
And I gotta add the key anyway, quote.id. And you can see where this is gonna start falling apart on me immediately. It's like, yo, you ain't got no ID on a quote. You're like, I absolutely do, I saw the type and it's like, I don't. So let's just put the rest of the content.
[00:02:49]
And that is filling in the props because it knows what the props of InspirationalQuote the component are. So again, I don't. If there's one reason beyond all of the safety and the good and the bugs you won't have is not having to remember what props you gave a component, particularly when you're live coding.
[00:03:06]
But also in your normal day to day life is worth it. For every work project, I use TypeScript. But even when I'm working on a course that's only JavaScript, I will write the app in TypeScript first. That is the person I have become over the last four years, is I will write in TypeScript first, and then I will simplify it to JavaScript afterward, right, cuz the benefits are that worth it to me.
[00:03:40]
Cool, so I'm getting yelled at, and I hover over, I can see why. quotes is this type, it's an array of never, right? Which again, when I start a heavy metal band, will be our first album. I'll get a SoundCloud between now and then. An array of never.
[00:04:05]
And because it's like, yo, you said you gave me an array. That's it, I don't know anything else about this array. And so any has two siblings, both, they seem scarier than any but are ultimately less bad. There's some kind of fiction that I could write about all of this.
[00:04:28]
If anyone's in the market for TypeScript fiction, let me know. So there's any, which means it could be anything. There is unknown, which is almost always what you want if you think you want any, which is like I don't know what this is. Which then says, figure it out before you use it instead of infecting everything.
[00:04:49]
And then there is the bottom, which is never, which is this isn't anything, right? And so it's looking at this array and goes, if there was stuff in this array, it'll be like, it's an array of those things. It's an empty array, so it's an array of nothingness.
[00:05:02]
It's an array of never. So the easiest way to handle that is exactly how we handled it before. And so we can basically say this is an array of Quote. There is a version of me. If anyone finds possibly even my current code base in the open source where I used to make pluralize versions of every type that were the array of that type, I no longer do that.
[00:05:26]
The one character just wasn't worth it. So Quote, and we say that is an array. And now, even though there's no quotes in it, it knows it's the right thing. I'm no longer being yelled at, right? I just had to help TypeScript along the way. And then in exchange, TypeScript helped me, and it now knows that it has these properties, so on and so forth, right?
[00:05:48]
And it all compiles as you can see down there. I do need to fetch these quotes at some point, but that's a later me problem. Because I have a new problem that I have to deal with for reasons that are mostly a setup to have to explain something to you, you'll notice that the button is not in this component.
[00:06:09]
It's in this Quotes plural component that I have to go into, right? And there, we have our onSubmit, or we can have an onSubmit. But there, we have the full form in which I can load Quotes. So I have the age old problem in React, which is I have to pass down everything I need from the parent component to the child components, right?
[00:06:35]
And there are a bunch of ways that I could do this. I could wrap setQuotes in a function and pass it down, but I could just pass setQuotes down through as well, or I could theoretically, it takes an onSubmit. I have multiple ways that I could deal with this.
[00:06:52]
The tricky part, not really the tricky part with figuring out is, what is this type? And there are a bunch of ways to do this one, there's nothing wrong with stealing this type. This looks somewhat confusing, but again, like I said before, useState has a wrapper over useProducer.
[00:07:11]
And so it's just dispatching a very simple object, which is whatever the new state is, and updating that accordingly. So I can have all that in place, and then I can pass that down if I need to, or anything that happens along the way. And set that all up, right?
[00:07:24]
And so for instance, I could pass on the direct value, I'm gonna pass in that onSubmit handler that we saw before. I can just go and say, so the count should be, we need to store the count to figure out how many to get. Now, that could happen in either component, we'll pass down the onSubmit But I need the count too, right?
[00:07:54]
That's interesting, as if he says that was some amount of surprise. All right, so I could pass down the whole set of quotes, or I could figure out one way or the other. I can move, I either lift my state up and have counts in that higher level component, right?
[00:08:10]
Which will now trigger rerender of everything whenever that count changes, cuz now every parent then rerenders all of its children, right? So that's great for state management. And yeah, I'm not worried about performance in this application. But what if I needed to actually pass through, I could also pass down setQuotes too.
[00:08:34]
And then we get the challenge figuring out how to type this, Right? And so we'll pass this through. And so what type? This is currently in any, right, on purpose to show you that nothing got yelled at as soon as I did that, right? It's like, yo, you're passing random props in anything you want.
[00:08:55]
One, any anywhere, and now, all of these, guess what. Everything is now in any, even if we could guess what it was, yeah?
>> Why do they have any if it's something you shouldn't even use?
>> So I mean, if you pull in a JavaScript library, right, and it doesn't have types, you need something, right?
[00:09:15]
You need the concept of an any.
>> Just for us.
>> Yeah.
>> While we're working through.
>> Yeah, exactly, right? It's a situation because JavaScript happens to predate TypeScript, right, that you could run into. And so I think it's really great for migrating. There are even ES lint plugins.
[00:09:36]
In our code, base we have an ES lint plugin, you can't even use any if you want it to, right? To make sure that, yeah, cuz anything it touches, if you had a function that is like, yo, I only take a number, right? You can pass in any in there.
[00:09:53]
And guess what the value is now, or guess what the return value is now too. It's in any, everything in any touches turn everything else along the way into an any, which is not great. So we'll say type, QuotesProps, And well, we know we don't need to put the children in there, right?
[00:10:19]
This is like pulling every, it's a review. We know that count, if we're gonna pass count in. Apparently, we can do that. Let's do that one. count will be a number. We're gonna go a different way. We'll see both ways in a second. I'm not gonna pass, I'll do both ways, we'll see it.
[00:10:35]
onChange, we know how to handle. This is everything coming together. And we know that's on an input element, which again, I can go verify as well. We know that there is a, We'll do this first, I'll show you if I needed to pass in the other thing. FormEventHandler.
[00:11:05]
And like I said, I am so happy I don't have to do this all from memory. And if you're stressed out looking at how does he know all these things, I don't. I'm literally using the auto complete and the intelligence to help me here. And then children, we know that we have an answer for that as well.
[00:11:24]
So if I just did QuotesProps, All right, it's like, yo, what about children? And I could add it in there as a React node, but as we saw before, I can do. Cool, and now let's see. Save that all we got. It doesn't know what event is here or onChanges, right, cuz that's wrong.
[00:11:58]
But that caught the bug. I remember when I was going through this before, I was like, that's wrong. I'm like, yeah, I would like to be notified about it. You have to believe me that I did that on purpose, I did. Cool, and so that passes in. I immediately found that little bug that would have bitten me at some point or another.
[00:12:14]
I've been like, yo, there is no onChange, and you called this a function. I would have found it at runtime. And then we wanted to say, with this point we are passing in count, and we'll do both ways. Default count to 10. And so you can see as I do this refactor, I will know when I am good because they're my sidebar and the red squiggles will tell me.
[00:12:42]
So it's like count needs to be a number in this case. And then I don't really care about onChange, right, I don't really have anything for that. So we're gonna make that optional in a second as we pull everything together. And so here we'll say, That our set, fetchQuotes, that takes a number, right?
[00:13:10]
And so this refraction becomes super easy as I go through, and then we'll, setQuotes. You can still make little mistakes, especially if you're talking and coding. And I roughly get that everything is gonna work as expected. I was about to say, my onChange should yell at me. onChange is missing in the type, and so I don't need that per se.
[00:13:37]
And if it feels like I am reinventing parts of HTML, that's a good feeling, we'll talk about that. So we'll save that, and everything compiles, right? Let's verify. Cool, other than some markup changes, I think I have a double. I can get rid of that. Piece that I left in there from earlier.
[00:14:07]
And everything works.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops