Call child's function from a Parent component in React

avatar

Borislav Hadzhiev

Last updated: Jul 25, 2022

banner

Photo from Unsplash

Call child's function from a Parent component in React #

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.

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.

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

  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 re-run 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 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.

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.

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.