Hooks 11 exercises

Specify the Initial Value with useRef

Like we've done before, we'll start by CMD + Clicking into useRef to check its type definitions.

When we call useRef with no arguments, it returns a MutableRefObject with a type of T or undefined.

function useRef<T = undefined>(): MutableRefObject<T | undefined>;


Loading solution


0:00 Let's examine why this is happening. If we command-click into useRef, we can see that by default here, T is undefined. This type is undefined. What's happening is that when we call useRef with nothing inside here, then whatever we put as the type argument is going to return it in a MutableRefObject with T or undefined. In other words, undefined is going to be part of this union.

0:28 This ref now, if we look at ref.current, ref.current is going to be HTMLDivElement or undefined. Undefined, as we saw in the previous explainer, you can't pass that into this current piece here. This current ref.current, imagine if we pass undefined here, that's not going to be happy. It's exactly the same because ref.current might be undefined.

0:56 The reason it's undefined is that when we initially do this, this thing here, is that if you don't pass in an argument here, then JavaScript will default it to undefined. We need to match what React is setting the runtime value to.

1:15 Let me just readjust this. We need to put into here. Now this is something that's pretty contentious. It's something that I've personally spoken to Sebastian Silbermann about from the React team to try and get this typing changed.

1:32 Because it's pretty not very ergonomic at all, this useRef passing in manually in order to match React's concept of what the proper nullish value should be between or undefined is just another example about why was such a massive costly mistake.

1:53 This is how you handle the typing refs that you need to pass into DOM elements here. Use useRef passing in the correct elements. Of course, if I put in the wrong one here, like HTMLSpanElement, this is going to be incompatible. It has to be the right element. Then you stick in here.

2:13 If you're ever not sure which element to pick, then you can hover over this and you'll be able to see HTMLDivElement just right there. If, for instance, we do audio instead, then this will need to be HTMLAudioElement. There we go. Copy from there. It's going to be plastered all over the error messages that you're getting there, as well as the hovers there, too.

2:34 This is the pattern that you'll need to fall into if you want to use useRef passing it into DOM elements.