This course has been updated! We now recommend you take the Intermediate React, v5 course.

Check out a free preview of the full Intermediate React, v4 course:
The "useImperativeHandle" Lesson is part of the full, Intermediate React, v4 course featured in this preview video. Here's what you'd learn in this lesson:

Brian explains why the useImperativeHandle is rarely used and only applicable for library development. By combining useImperativeHandle with forwardRef, component methods can be customized and exposed to a parent component.

Get Unlimited Access Now

Transcript from the "useImperativeHandle" Lesson

[00:00:00]
>> So the next one, if we pull this back out, is useImperativeHandle Example. I'm going to venture and say you will never use this, let's do it [LAUGH]. This is for libraries, I'm showing you something that is really just for libraries that are building something on top of React, for something like Formik, right?

[00:00:20] I haven't looked at what Formik does underneath the hood, but I would very likely think that they would use ImperativeHandle underneath it. So, I do not blame you if you don't go through this thoroughly. It's good to know that there's something like this exists, but you don't really need learn it in depth.

[00:00:39] So let's talk through the use case really quick here, I have this useImperativeHandle Example right here. And I have a city and state here, right? Let's say that I have some form that I wanna validate that everything works correctly, right? So I have in here Seattle, and let's say the person forgot to put in the state.

[00:00:57] And I wanna highlight this in red if the person didn't do it correctly, right? Pretty normal stuff, right? There's other ways you can do this, but I'm gonna show you how to do it with useImperativeHandle. So we're gonna have two things here, one's called forwardRef, which you have to use with the useImperativeHandle.

[00:01:19] And we have this function here called useImperativeHandle. So let's start here with our ImperativeHandleComponent here. You can think of this like elaborate input function, as like a piece of library code, right? This would be something like maybe your design system teams might make. It might be something that an open source library that you might be using.

[00:01:41] But typically, you, developer working on an app, you are not going to be writing something like elaborate input yourself, you're going to be consuming it, okay? So we're writing this form, right? And we have an ImperativeHandle component here. It's got a state, it's got a city, and it has an error state as well.

[00:02:03] So here with city element and state element, what this library might ask you to do, is you can see down here. We're passing a ref into the elaborate input here and here, right? Okay, this becomes important, because later we write this function here called validate. Which again, I just directly stole this from Stack Overflow, barely modified it at all, so normal programming kind of stuff, okay?

[00:02:36] So if this doesn't work, blame Stack Overflow, don't blame me. Okay, so this just does a check to see is the city a valid city, right? And is the state a valid state. And then here, if this matches, which means there's an error in the city, right? But I do as I said, there's an error on city, so setError("city") right there, right?

[00:02:57] And then here, I call a function on the current here so that it focuses, right? So this becomes important here, right? Because if someone's writing something here, and they say, let's just refresh the page, stay on page, we can refresh it up here. Down here, if the user has a problem here, I want the focus to go on that input, right?

[00:03:26] So if I hit Delete here, notice I'm not focused on it, but if I click Validate Form, now I'm focused again here, that's what I want to happen. So that's where this forwardRef and useImperativeHandle gets helpful. So one, this is not possible unless you do the forwardRef thing, right?

[00:03:46] And then here, I put the ref here on the input, right? And then this forwardRef allows me to expose this ImperativeHandle here. Which allows a person to call the ref.focus to allow me to focus on that input. I'm inverting the control here, that's really the sum of the stories.

[00:04:17] I'm inverting the control that typically I ElaborateInput itself with call, hey, I want you to focus on this, right? Typically I would just pass in something, I would use the normal one-way data flow. But if I don't write that ElaborateInput, if that's library code, I need some way to expose that to the user, which is what I'm doing here with input.current.focus.

[00:04:40] Because the ref is controlled here by the ImperativeHandle component, Which I made, Here, right, wherever I made that ref, hit these refs. So you might be looking at this as like, I don't really get it or care about it. Both of those are totally fine, I just want you to know that this is out there.

[00:05:06] That if you somehow need to have this inverted control in your application, one, rethink about what you're doing, right? If you control all of the code top to bottom, you can remodel this in a better way. Where basically you just pass in an error state here, and then you call focus on that directly in the child's component yourself.

[00:05:24] But if you don't control that, this is how you would handle that. So, you're going to use this either if you're an open source maintainer, or if you're making a design system. Cuz even this, again, imagine that you don't write this, this is something that's coming in from a library.

[00:05:46] This is still a weird API that you have to make a ref and pass that in, right? Most people are gonna be like, why am I doing this? So, anyway.