DEV Community

Cover image for Calling Child Component Function From Parrent Component ( forwardRef and useImperativeHandle)
Sasa Milosevic
Sasa Milosevic

Posted on

Calling Child Component Function From Parrent Component ( forwardRef and useImperativeHandle)

For calling functions from parent component that are declared in child component we are using React.forwardRef and React.useImperativeHandle hooks from React.

React.ForwardRef

React.forwardRef creates a React component that forwards the ref attribute it receives to another component below in the tree.

React.forwardRef accepts a rendering function as an argument. React will call this function with props and ref as two arguments. This function should return a React node.

const CustomButton = React.forwardRef((props, ref) => (
  <div ref={ref}>
    {props.children}
  </div>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<CustomButton ref={ref}>Click me!</CustomButton>;

Enter fullscreen mode Exit fullscreen mode

React.useImperativeHandle

useImperativeHandle customizes the instance value that is exposed to parent components when using ref. As always, imperative code using refs should be avoided in most cases. useImperativeHandle should be used with forwardRef:


useImperativeHandle(ref,
    () => {
        yourFunction: () => {
        //function content
         } 
    });
Enter fullscreen mode Exit fullscreen mode

EXAMPLE:

Create a parent component first, with a button to call a function from child component that we will create in few moments.

import React from 'react'
export default function ParentComponent() {
    return (
        <React.Fragment>
          <h1>Parent Component</h1>  
          <button onClick={()=>{ }}>
            Call Child Component Function
          </button>
        </React.Fragment>
    )
}
const ChildComponent = () => {}
Enter fullscreen mode Exit fullscreen mode

Now, we are creating a child component using forwardRef and render component in the parent with a ref created with Reac.useRef. Now, the function childComponentFunction() is stored in .current property of ref and we can use it anywhere in the parent component.

import React, { forwardRef, useImperativeHandle, useRef } from 'react'

//Parent Component
export default function ParentComponent() {
    const childRef = useRef();
    return (
        <React.Fragment>
            <h1>Parent Component</h1>
            <button onClick={() => { 
            childRef.current.childComponentFunction()
            }}
            >
               Call Child Component Function
            </button>
         <ChildComponent ref={childRef} />
        </React.Fragment>
     )
}

//Child Component
const ChildComponent = forwardRef((props, ref) => {
    useImperativeHandle(
        ref,
        () => ({
            childComponentFunction() {
                alert("Child component function called")
            }
         }),
     )
     return (
         <h3>Child Component</h3>
     )
})
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
ekeijl profile image
Edwin • Edited

The information here is technically correct, but should only be used as a last resort, for example when you're integrating with a third party library that is hard to integrate with React and requires you to call a function on it directly.

In 99.9% of the cases, you want to communicate with the ChildComponent by passing it new props that reflect the update.