Typing useRef Elements0:07
Let's talk about how to use TypeScript with common react hooks that you'll probably use in your React Laravel application. So here I have just a simple demo component. It's completely empty right now, but let's add something to it and enhance it with a TypeScript. So whenever you need a reference to a dom element that is rendered by your component, you would use the use ref hook, right?
that is rendered by your component, you would use the use ref hook, right? So let's set that up. Constant div ref equals use ref and we'll say return diviv ref, diviv ref. There we go. Now ref needs to default to something, right? So we'll default it to no. So this is totally valid, totally works, it will work. Ultimately, if you use this as it is, uh,
So this is totally valid, totally works, it will work. Ultimately, if you use this as it is, uh, but you don't get any type information out of this, you have no idea what's going on. So if we said Diviv ref current, there's just nothing here that's useful for us. But we know that this is referencing a diviv element and types script has built in a bunch of the TML elements, right? So we can use HTML Diviv element
TML elements, right? So we can use HTML Diviv element and automatically this becomes a ref object that's either an HTML div element or null automatically, right? Because once it mounts, it will become a reference, but before that it will be null. So now we get some very nice auto completion for this, right? So we get a bunch of stuff that TypeScript supplies to us about what we can access on this Diviv
So we get a bunch of stuff that TypeScript supplies to us about what we can access on this Diviv ref, which is pretty rad. And the same thing goes for say if you had like an HTML image element, right? You can just grab that and now you can say image element specific things such as like source, source set, current source. It's really useful to enhance the references using types. You just get a lot more intelligence around it
Typing useState Values1:59
It's really useful to enhance the references using types. You just get a lot more intelligence around it and you know what's available to you from that reference. Okay, next up, let's talk about state. So we're gonna do a very simple state, we'll do a constant count, set count, classic equals use. State one. Okay, let's import use state. Perfect. So now we can see that count is a number, it's inferred and set count only accepts a number, right? So if we did set count
and set count only accepts a number, right? So if we did set count and we passed in, true, it's gonna be upset with us. It doesn't like that type. Boolean is not assignable to type of number, okay? So if we pass in one, we're good to go. This is great. I would say nine times outta 10. You probably don't need to explicitly type your state, but there are some differences. What if your account is not actually initialized
but there are some differences. What if your account is not actually initialized as a number for some reason? What if it's initialized as null? Well now suddenly the only thing this is going to accept is null. It's the only thing you can pass in, but you do want to at some point initialize that counter so you can say number or null, right? So now if you pass in two, that's valid.
so you can say number or null, right? So now if you pass in two, that's valid. If you pass in null, that's valid. If you pass in true, that's invalid. So you can specify what is allowed here by using the generic unused state. Again, nine times outta 10, you probably don't need to do this, but it is good to know about. Okay, next up let's talk about use memo. So if we said cons, attributes
Typing useMemo Returns3:29
Okay, next up let's talk about use memo. So if we said cons, attributes equals Hughes memo and then we have a factory to set this up. And then we say, let's use count as a dependency here. And what if we said if count is greater than zero return, title, something, description, something, otherwise just return something else, right? So hi. Hello.
something else, right? So hi. Hello. Okay, so it's being inferred, right? It's being inferred that title and description R coming back. Okay? And that's totally fine. Also, please note that count is possibly null. So now that we have uh, some type safety around this count could possibly be null, but let's just, let's just fix that
around this count could possibly be null, but let's just, let's just fix that by doing this and we'll say one. Okay? So we have this, and whenever I see this, I do want to establish a contract, right? I kind of wanna say if it's coming back in multiple places, I wanna ensure that what I get is what is promised. So for example, if we just leave out a description, but we are expecting description, this would be a problem.
So for example, if we just leave out a description, but we are expecting description, this would be a problem. So let's just establish a little contract here. We'll take this and we'll just say this is a string and this is also a string. Okay? So now we're explicitly saying this is what should be coming back. So if we do this, it lights up red, it says, Hey, you promised to return a description property, you haven't returned a description property.
you promised to return a description property, you haven't returned a description property. So things like this, things like typos that become a non-issue. Again, you don't always need to explicitly type this stuff, but I think if you have any sort of logic that's returning something resembling this in your used memo, I would recommend just establishing a contract via the generic. And that's how you use type with built-in react hooks.
contract via the generic. And that's how you use type with built-in react hooks. Again, I would start with inference. Let TypeScript figure out what it is that you're returning and then pepper in types when you feel like they're necessary or when you feel like you need stronger typing in that hook.
