Call a Child function from a Parent component in React

avatar
Borislav Hadzhiev

Last updated: Jan 18, 2023
3 min

banner

# Call a Child function from a Parent component using useImperativeHandle

To call a child's function from a parent component in React:

  1. Wrap the Child component in a forwardRef.
  2. Use the useImperativeHandle hook in the child to add a function to the Child.
  3. Call the Child's function from the Parent using the ref, e.g. childRef.current.childFunction().
App.js
import {forwardRef, useImperativeHandle, useRef} from 'react'; const Child = forwardRef((props, ref) => { useImperativeHandle(ref, () => ({ childFunction1() { console.log('child function 1 called'); }, childFunction2() { console.log('child function 2 called'); }, })); return ( <div> <h2>child content</h2> </div> ); }); export default function Parent() { const childRef = useRef(null); const handleClick = () => { childRef.current.childFunction1(); childRef.current.childFunction2(); }; return ( <div> <Child ref={childRef} /> <h2>parent content</h2> <button onClick={handleClick}>Call child functions</button> </div> ); }

call child function from parent

We used a forwardRef to forward a ref from the Parent component to the Child.

The forwardRef method accepts a function that takes the props and a ref as parameters.
App.js
const Child = forwardRef((props, ref) => { useImperativeHandle(ref, () => ({ childFunction1() { console.log('child function 1 called'); }, childFunction2() { console.log('child function 2 called'); }, })); return ( <div> <h2>child content</h2> </div> ); });

The function we pass to forwardRef should return a React node.

We need to forward the ref to the Child so we can use the useImperativeHandle hook to customize the Child's instance value that is exposed to the Parent component when using a ref.

App.js
useImperativeHandle(ref, () => ({ childFunction1() { console.log('child function 1 called'); }, childFunction2() { console.log('child function 2 called'); }, }));

The Parent component that renders <Child ref={childRef} /> will be able to call childFunction1 as childRef.current.childFunction1().

Alternatively, you can use a more indirect approach.

# Call a Child function from a Parent component using useEffect

This is a three-step process:

  1. Declare a count state variable in the Parent component.
  2. Add the count variable to the dependencies of the useEffect hook in the Child.
  3. Increment the count in the Parent to rerun the child's useEffect.
App.js
import {useEffect, useState} from 'react'; const Child = ({count}) => { useEffect(() => { const childFunction1 = () => { console.log('child function 1 called'); }; const childFunction2 = () => { console.log('child function 2 called'); }; // ๐Ÿ‘‡๏ธ don't run on the initial render if (count !== 0) { childFunction1(); childFunction2(); } }, [count]); return ( <div> <h2>child content</h2> </div> ); }; export default function Parent() { const [count, setCount] = useState(0); const handleClick = () => { setCount(current => current + 1); }; return ( <div> <Child count={count} /> <h2>parent content</h2> <button onClick={handleClick}>Call child functions</button> </div> ); }

call function in child component

The Parent component declares a count state variable and passes it as a prop to the Child.

We added the count variable to the dependencies of the useEffect hook, so every time it changes, the function we passed to useEffect is going to run.

App.js
useEffect(() => { const childFunction1 = () => { console.log('child function 1 called'); }; const childFunction2 = () => { console.log('child function 2 called'); }; // ๐Ÿ‘‡๏ธ don't run on initial render if (count !== 0) { childFunction1(); childFunction2(); } }, [count]);

The Child component declares and calls 2 functions in the useEffect hook.

The Parent can run the logic in the Child's useEffect hook by changing the count state variable.

Notice that we check that count is not equal to 0 before calling the functions in useEffect.
App.js
if (count !== 0) { childFunction1(); childFunction2(); }

The useEffect hook is run when the component mounts and every time one of its dependencies changes.

If you don't want to run the logic on mount check that the count variable is not equal to 0 before calling the functions.

Conversely, if you want to run the Child function from the Parent component when the Child mounts, remove the conditional.

App.js
const Child = ({count}) => { useEffect(() => { const childFunction1 = () => { console.log('child function 1 called'); }; const childFunction2 = () => { console.log('child function 2 called'); }; // ๐Ÿ‘‡๏ธ Call function on Mount as well childFunction1(); childFunction2(); }, [count]); return ( <div> <h2>child content</h2> </div> ); };

react call function in child from parent on mount

The code sample calls the Child function from the Parent component when the components mount and every time the button is clicked.

We simply removed the if statement that checks if the count state variable is equal to 0.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev