تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

App Component Overview1:06

So let's go ahead and get started. A quick overview of the components I have here, app is the parent, and this is where our to-do state lives. So we have some default to-dos here, and all of the functions that have to do with to-dos are defined in here, and then we pass them down into the components that need them. So here are our to-dos. We have an ID for to-do, just so the ID changes as we add them, and here are our functions. So addTodo, deleteTodo, completeTodo, and so on. And as you can see, we have a few child components here. So we have the TodoForm, which is this part right here, and we're passing the addTodo

And as you can see, we have a few child components here. So we have the to-do form, which is this part right here, and we're passing the addToDo method into that component. We have the to-do list, which is the list, as well as the checkAll and itemsRemaining, and we pass in all the methods we need, and also the toDos as props, and we just have this NoToDos component, which is just an SVG that shows when we have no to-dos. So there it is, and there it is. So let's start in the parent App component. Let me just refresh here, go here, let's go into app, and let's start up here. So again, you can add a return type if you'd like to the functional component.

Create ToDo Interface2:54

So let's say new file, interfaces.ts, say export interface ToDo, and just grab these fields here and add types for them, okay? This is a number, this is a string, this is a Boolean, and this is a Boolean as well, okay? That should be good. Let's go ahead and import that within here. I'll put it right underneath here. So import ToDo from ../interfaces, okay? And to use that type for our to-dos and set to-dos, we can use the generic syntax, which is angled brackets right here.

Type App Methods4:04

All right, what's next? We have this ID. So the inferred type is a number, which is correct. So I'm not gonna bother adding the type here, but you can if you like. Say number, I guess we'll just leave it. Next we have addToDo. Again the return type is inferred to be void, which is correct. Since we're not returning anything here, I'm just gonna add it to be explicit. But generally speaking, you don't see it if the inferred type is correct. Now what is this toDo param?

But generally speaking, you don't see it if the inferred type is correct. Now what is this to-do param? As you can see, it's inferred to be any, which we don't want. And based on the name, to me it looks like it's a to-do object, but it's actually a string. So as you can see, we are adding the title here. So a better name would be to-do title. And then we can change this as well. And then we can give it the correct type. So that should be a string. So we're using this function in the to-do form right here.

So that should be a string. So we're using this function in the to-do form right here. You can see we're passing it down as a prop right here, and then we're calling it after we hit submit. And the to-do input is the string that the user types into to add a new to-do right here. So that is good. What's next? We're also incrementing the ID for to-do here. Let's see the inferred type. It is number, which is correct.

Let's see the inferred type. It is number, which is correct. And usually I just leave it, but I'm trying to be explicit in this video. So we will add the number type here. You have to add an extra bracket here. Okay. Save that to make sure everything's still working. Okay, no errors. For deleteToDo, let's see the inferred return type. void is correct since we're not returning anything.

For delete to-do, let's see the inferred return type. void is correct since we're not returning anything. Again, I'm going to be explicit here. What is the ID? Let's see if we hover over this. Okay, it's inferring it as any, which we don't want. And ID is obviously a number. So let's add that. And let's check this type here. If it's inferred to be an actual to-do, it is.

And let's check this type here. If it's inferred to be an actual to-do, it is. But if you want to be explicit, like I'm doing here, we can set this to an actual to-do. So let's go ahead and do that, say to-do. And that should be fine. Let's work on complete to-do here. Again, not doing anything here. So void is correct. Or we're not returning anything, I mean. ID is number.

Or we're not returning anything, I mean. ID is number. So let's check the inferred type of updated to-dos. Should be a to-do array. And it is because it knows the type of to-dos and it knows map should return the same array. So the inferred type is correct. But again, if you want to be explicit, we can say colon to-do array. And the inferred type for to-do should be a to-do. It is. But we are going to set it to a to-do here.

It is. But we are going to set it to a to-do here. So I'm just doing this so you can get used to the syntax. But again, you don't have to define it if the inferred type is correct. Okay, and everything else looks good. Let's save. What's next? Mark as editing. Again, we're not returning anything. So void ID is a number.

Again, we're not returning anything. So void $id is a number. This should be a to-do array, and it is. But I'm going to be explicit. Same for this. It's getting repetitive, but stick with me if you can. Need an extra bracket here. And that should be good. Next up, we have updateTodo. And we do have an event here.

Next up, we have update to-do. And we do have an event here. We are not returning anything. So void again, ID is number. So let's see what type this event should be. Actually, we can type these two as well. So to-do is to-do, like we've been doing. And updated to-do should be a to-do array. And if we hover over event, I believe it's going to infer it as any. But if we take a look at where we're actually using it, so we're using it in the to-do list.

Union Types for Events8:04

And if we hover over event, I believe it's going to infer it as any. But if we take a look at where we're actually using it, so we're using it in the to-do list. So let me save this for now. Actually, let's set it to any for now. Let's go to to-do list. And let's look at where we're using updateToDo. So we're using it in two places, onBlur and onKeyDown. So that's because we can updateToDo in these two cases. So the first case is onBlur. So that's when we focus off the text box.

So the first case is onBlur. So that's when we focus off the text box. And one is when we're pressing the Enter key, as I listen here. So let me just show you that in the browser. Let's refresh this to make sure. So it's when we're editing a to-do. If I edit it and press Enter, that's one event. But if I edit it and blur off of it, or focus off of it, that's the other event, and that should work as well. So it's happening in those two cases.

should work as well. So it's happening in those two cases. So the event might be different. So for onBlur, if we hover over it, you'll see it's React.FocusEvent. But onKeyDown, it's React.KeyboardEvent. So we can make use of the union type, or the pipe operator, like I showed you in the last video. So let's grab this one. Let's put that in our event type for our App.tsx. So right here, that's one of them.

Let's put that in our event type for our app TSX. So right here, that's one of them. And then the other one, the other type for onKeyDown. So let's grab that one as well. So this one, it's React.KeyboardEvent. And let's paste that in. And it looks like Prettier did some formatting here, but hopefully this still works. Let's double check. Let's see if we can still commit the change with Enter, and also with Blur. Okay, so it still works.

Let's see if we can still commit the change with Enter, and also with Blur. Okay, so it still works. And we have the correct event type now. There are a few more methods here, which we will do. CancelEdit also has an event, id is a number, return type should be void. And let's check out where we're using CancelEdit. Again, it's in the to-do list. CancelEdit, there it is. And it should be the same as onKeyDown, like we just took a look at. So React.keyboardEvent, okay.

And it should be the same as onKeyDown, like we just took a look at. So React.keyboardEvent, okay. Let's type that. And this is the same. So toDo array, and toDo. Okay, save that. What's next? This is the same thing, so I'm just going to edit this in. void, toDo array, and toDo. And our last method here is remaining.

Void, to-do array, and to-do. And our last method here is remaining. So this is actually returning something, and it knows it's an array using .length. So it should infer number. And it does, but we are being explicit, so we'll say number here. And we can also say this is a to-do. Okay. That should be it for our app component. The JSX should stay the same. So let's move on to our to-do form.

Type TodoForm Props11:23

The JSX should stay the same. So let's move on to our to-do form. So for our to-do form, you can see that we are using PropTypes here to verify the props. And the only prop coming in is this addToDo function, and then we're using it down here. I'm actually going to destructure it from here instead. So let's say addToDo. And then we can just get rid of this here. Okay. Okay, let's save that. But now we're going to use TypeScript instead of PropTypes to verify our props.

Okay, let's save that. But now we're going to use TypeScript instead of PropTypes to verify our props. The main difference between the two is that PropTypes verifies them on runtime, whereas TypeScript verifies them in development. So you can still use both of them if you like, but they are kind of doing the same thing. And if you're using TypeScript already, it's probably better to just use TypeScript. So just like I showed you in the last video, we can make an interface for our props. So let's say interface Props. And the only prop that's being passed in is this addToDo method. So to define methods as props here, we can say addToDo. It is a method that returns.

So to define methods as props here, we can say addToDo. It is a method that returns. So let's take a look at app.tsx. Let's look for addToDo here. So it returns void, and it takes in a to-do title. That's a string. So it returns void, and it takes in a to-do title. That is a string. And now that we have this, we no longer need to use PropTypes. Let's get rid of this.

So for our two methods here, we have events, and they are inferred as any. So let's do the same trick here where we do it inline and check what the event is in VS Code. So for handleInput, let's do it inline here on the input right here. Let's just say e, and then we can hover over here, and we can see it's a React.ChangeEvent. So let's grab that. Okay. And let's put that back. Let's add it to our handleInput for the event type. And again, you can put it as void if you like. And let's do the same for our handleSubmit.

And again, you can put it as void if you like. And let's do the same for our handleSubmit. So let's just say e here. Let's check out the event type. It's a React.FormEvent. Let's grab that. Let's put that back. And let's add the type here for handleSubmit. And this is void as well for the return type. Okay.

And this is void as well for the return type. Okay. That should be it for this component. Maybe we can add the return type for the entire function. And you don't have to do this, but you can see the inferred type is JSX.Element. So we can add it here, JSX.Element. Okay. Let's take a look at our console to make sure there are no errors. Everything looks good. So let's move on to the next component.

Type TodoList Props14:36

Everything looks good. So let's move on to the next component. This will be our to-do list. Scroll up here. And it's basically the same thing, just replacing our prop types here. Let's go ahead and do the same thing and define an interface for our props. interface Props. And then we have all of these fields here. So let me just grab all of this.

And then we have all of these fields here. So let me just grab all of this. Paste that in. And let's go through these. toDos is a to-do array. So we have to import that. Let's go ahead and import that. Let's just grab it from our app. So it's this. Let's put that import here.

So it's this. Let's put that import here. Okay. completeToDo is a method. Let's take a look at that actually. completeToDo. It's a method that returns void and takes in a number. So id is a number. And it returns void. markAsEditing is the same.

And the type we already did. So let's grab that. These two here. Let's paste that in. The second param is an id of number. And that should return void. Hopefully Prettier reformats this. It doesn't. It's probably because these are not defined yet. So let me just put any for all of them for now. Just so I can get the formatting working. Okay. So that reformatted.

Just so I can get the formatting working. Okay. So that reformatted. cancelEdit takes in an event and an id. And again we have the event here. So let's grab that. Okay. It is a method. event is this. id is a number. And it returns void.

Id is a number. And it returns void. And deleteToDo is the same as these ones up here. So let me just grab this. remaining is a method that returns a number. Has no params. Okay. And completeAllToDos is a method. void. Okay.

Make sure there are no errors. And everything looks good. So I didn't destructure the props here. But if you want to do that, you can. But there are a good amount of props as you can see here. So if you destructure them here, it looks a bit messy. So you can just leave it like this. Or you can destructure it underneath if you like. So I'm going to do that. So we can just say const.

So I'm going to do that. So we can just say const. And then destructure all of the methods we're passing in. So toDos. complete. toDo. And so on. I won't make you watch me do that. And we can say equals props. Okay. So I destructured everything here.

And we can say equals props. Okay. So I destructured everything here. Now we can get rid of all of our props.calls. So let me just select all of them. And delete it. And hopefully everything is working. And again, if you want, you can return JSX element from this functional component. JSX.element. Okay. Save.

Okay. Save. That should be everything. Let me just add JSX element to this component as well. Okay. Save. Let's check out our console. Everything looks good. Let's check our actual app. And it looks like everything is still working.

Extract Render Helpers19:29

So that would be this case where it just shows the label. And the else case for that is when we are editing and it shows the text box here. So to make this a bit cleaner, we can extract these two methods that render either this or this. Let's grab the first case. So this is for the Todo that is not editing. Let's grab all of this. Let's say renderTodoNotEditing. And we need to call that as a method. Let's go ahead and define that up here. So let's put it right here.

Let's go ahead and define that up here. So let's put it right here. function render to-do not editing. Or like I said in the last video, you can use arrow functions if you like. This actually takes in a to-do. So let's accept that as a param. And we have to call it with that param as well. So let's add that. And let's go ahead and just return the markup that we copied. So return this.

And let's go ahead and just return the markup that we copied. So return this. Okay. Let's save it. Looks good. We can actually type this to be a to-do. Right now it's inferred as any, which we don't want. And the return type should be a JSX element. So let's see. It is.

So let's see. It is. But like I've been doing, let's just set it explicitly. Okay. And let's do the same for the other case as well. So let's grab this other block of markup. Okay. It should be render to-do editing. Pass in the to-do. And VS Code changed it to the wrong method.

Pass in the toDo. And VS Code changed it to the wrong method. Okay. Let's go ahead and add this method as well. Don't need these brackets anymore. Save that. Okay. And let's add that method up here. After this one. renderToDoEditing.

After this one. Render to-do editing. Takes in a to-do of type Todo. The return type is JSX.Element. And we can return what we copied. Okay. Let's save that. And hopefully I did everything correctly. And this still renders.

Example of using TypeScriptConverting PropTypes to TypeScript

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟