useImperativeHandle hook

everything you need to know about useImperativeHandle

Photo by Rahul Mishra on Unsplash

The hook name itself describes what it does.

React is declarative UI library.
Meaning we don’t have to worry about the steps of doing certain things like manually adding click listeners. We simply declare onClick and React Manages all the stuff under the hood.

And the counter part of declarative is imperative. Where we define all steps manually. Like attaching event listeners manually.

What does useImperativeHandle do?

useImperative gives us a way to update the DOM and it’s content without the use of state variables. As there is no involvement of state React won’t re-render the component, it’s the developers responsibility to update the UI in imperative manner.

UseCase:

When we have thousands of HTML blocks in the UI, and we have to show tooltip based on the clicked element, Now the easy way to do this is to use state variables to store the information about the clicked element, the downside of this is that component will be re-rendered.

We can manage this scenario by using useImperativeHandle

Let’s consider this example:
We have 100 blocks with number, and on click of each block we have to show the clicked number in a card.

Here, we have done it using state way, on click of any block, we are updating the state variable which is keeping track of selected block.
And once state is updated, react re-renders the UI with updated value.

Problem:
The green pulse shows the re-rendering done by react. As it is visible that on each selection whole UI is updated.
This can be a problem when the number of elements are larger.

We can solve this issue using useImperativeHandle. By updating the UI in imperative way, (Manual Way) instead of using state to update the UI.

How does useImperativeHandle works?

useImperativeHandle is a hook which takes 2 arguments

  1. ref passed by forwardRef
  2. A function which returns an object, containing all the methods which we want to expose to parent component.
useImperativeHandle(ref, ()=> ({hide:function() {}}))

Usage in Parent Component:

const childRef = useRef();function handleClick() {childRef.current.hide(); // will call the hide method defined in userImperativeHandle}return <Child ref={childRef} />

Solving the problem using useImperativHandle

Parent Component
Child Component

Demo:

No re-renders in case of useImperativeHandle

Extending the usage:

Here we have only updated a string, but generally we have a component to update. We can use ReactDOM.render method to update the content manually in case we have additional component used.


useImperativeHandle(ref, ()=> ({
updateUI() { // Step 1: Empty the current data
insideRef.current.innderHTML = '';
// Step 2: Create a dummy element
const temp = document.createElement('div');
// Step 3: Render the content inside dummy Element
ReactDom.render(<TooltipInfo data={data} />,temp);
// Step 4: Add the Content inside our Visible Component
insideRef?.current?.appendChild(temp.childNodes[0]);
// Step 5: Remove the dummy Element
temp.remove();
}}))

Caveats of useImperativeHandle:

When we pass ref inside useImperativeHandle, DOM reference of ref gets overridden by the returned object and none of the DOM methods will work on ref. Due to this assigning the same ref to any DOM element won’t work.
We have to create a separate ref in component and use it instead of the forwarded ref.

Thanks for Reading.

--

--

राहुल मिश्रा
राहुल मिश्रा

No responses yet