0

I need to call a function in a child component from a parent component with React Hooks.

I was trying to adapt this question to my use case React 16: Call children's function from parent when using hooks and functional component but I keep getting the error

TypeError: childRef.childFunction is not a function

My parent component is like this:

import React, { useRef, useEffect } from 'react';
import Child from './child'

function Parent() {
    const parentRef = useRef()
    const childRef = useRef()

    const callChildFunction = () => {
        childRef.current(childRef.childFunction())
    }

    useEffect(() => {
        if (parentRef && childRef) {
            callChildFunction();
        }
    }, [parentRef, childRef])

    return (
        <div ref={parentRef} className="parentContainer">
            PARENT
            <Child ref={childRef}/>
        </div>
    );
}

export default Parent;

My child component is like this:

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

const Child = forwardRef(({ref}) => {
    useImperativeHandle(ref, () => ({
        childFunction() {
            console.log("CHILD FUNCTION")
        }
      })); 

    return (
        <div className="childContainer">
            CHILD
        </div>
    );
})

export default Child;

What am I doing wrong?

4
  • Interesting, didn't know about this hook. But from the docs imperative code using refs should be avoided in most cases. Why not elevate the state to the parent. or use redux or context hooks to pass values and functions between components? Commented Jun 12, 2020 at 15:05
  • 1
    childRef.current(childRef.childFunction()) - is this intentional? shouldn't you be calling childRef.current.childFunction() directly? Commented Jun 12, 2020 at 15:08
  • The reason I want to do this is I have a child component that uses data from a context, and also takes data as an input, but the context is not refreshing in the child component when the context is reset from the parent - but the use case is very particular Commented Jun 12, 2020 at 15:43
  • I tried both childRef.current(childRef.childFunction()) and childRef.current.childFunction() - both produce the same error for me. I think I used the first one coz I was adapting the function from the example and they were using a forEach over an array of refs Commented Jun 12, 2020 at 15:46

1 Answer 1

1

I think this is your problem

    childRef.current(childRef.childFunction())

childRef.current isn't a function. Also childRef.childFunction() is run first, which also isn't a function.

childRef.current.childFunction should be a function, try childRef.current.childFunction() instead of childRef.current(childRef.childFunction())


From the docs on useImperativeHandle check out the usage of inputRef.current.focus():

function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);

In this example, a parent component that renders <FancyInput ref={inputRef} /> would be able to call inputRef.current.focus().

Edit based on comment for future visitors:

const Child = forwardRef(({ref}) => {

should be

const child = forwardRef(({}, ref) => {
Sign up to request clarification or add additional context in comments.

4 Comments

I had also mixed up refs and props. The ref isn't a prop so I had to put forwardRef(({}, ref) => { etc...
Thanks, updated answer for that for future viewers.
I have a question about how the parent would be able to call inputRef.current.focus()? How would you do that?
I don't use this methodology anymore. If I need something to run in my child, I either modify a prop that is inbound or do something to make useEffect run. I think it's kind of an anti pattern.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.