Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React 16: Call children's function from parent when using hooks and functional component

I need to call children's function in their parent component. How should I do it? Previous in React 15, I can use refs to call children's function. But have no idea how to do it with hooks and functional component.

function Child(props) {
    function validate() {
        // to validate this component
    }

    return (
        <>Some code here</>
    )
}


function Parent(props) {
    const refs = useRef([]);
    const someData = [1,2,3,4,5];

    function validateChildren() {
        refs.current.forEach(child => {
            child.current.validate(); // throw error!! can not get validate function
        });
    }

    return (
        <>
            <button onClick={validateChildren}>Validate</button>
            {
                someData.map((data, index) => {
                    return <Child ref={ins => refs.current[index] = ins} />
                })
            }
        </>
    )
}

My actual requirement is: 1. There are multiple tabs which can be added, delete base on user's behaviour 2. Click a button in the parent of tabs to trigger validate 3. All the tabs need to validate itself, show error message in their tabs and return a validate message

like image 461
Clark Avatar asked Sep 21 '19 03:09

Clark


1 Answers

You can use useImperativeHandle with forwardRef.

From the docs,

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

const Child = React.forwardRef((props,ref) => {

    //validate will be available to parent component using ref
    useImperativeHandle(ref, () => ({
      validate() {
        // to validate this component
        console.log("I'm clicked");
      }
    }));

    return (
        <>Some code here</>
    )
})

In the parent compoennt you can access child function as,

function validateChildren() {
   refs.current.forEach(child => {
      child.validate(); // you can access child method here 
   });
}

Demo

like image 123
ravibagul91 Avatar answered Sep 29 '22 08:09

ravibagul91