DEV Community

Samith Dilhara
Samith Dilhara

Posted on

usage of useImperativeHandle hook

Before we move into the usage of useImperativeHandle, let’s discuss the problem this hook is trying to fix.

Here we have defined the App component and Input component, The goal of the application is to focus the input when the button element is clicked.

with a forwardRef this is pretty simple right?

const App = () => {
      const inputRef = useRef(null);

      const handleClick = () => {
        inputRef.current.focus();
      };

      return (
        <>
          <Input ref={inputRef} />
          <button onClick={handleClick}>click to focus child input</button>
        </>
      );
    }

    const Input = forwardRef((props, ref) => {
      return <input ref={ref} {...props} />;
    });
Enter fullscreen mode Exit fullscreen mode

However, in this solution, the parent component App has full access to the input element in Input component, the inputRef declared in App holds the full DOM node for the child input element.

but if you don't want to give full DOM node access to the parent, you can achieve it using useImperativeHandle hook. you can just expose only the focus function for the parent

Updated Input Component

const Input = forwardRef((props, ref) => {
  // create internal ref object to hold actual input DOM node 
  const inputRef = useRef();

  // pass ref from parent to useImperativeHandle and replace its value with the createHandle function
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));

  // pass internal ref to input to hold DOM node
  return <input ref={inputRef} {...props} />;
});
Enter fullscreen mode Exit fullscreen mode

useImperativeHandle accepts the parent ref and a callback function as arguments, the function should return an object to replace the current property in parent ref, so focus is the only function which App can access now.

In this way, we can limit/expose functions/properties to parent components using ref

Top comments (0)