简体   繁体   中英

Trigger child function from parent component using react hooks

I have some action buttons in parent components. On click of one of such buttons, I would like to trigger a function in the child component. Currently, I am trying to implement it using useRef hook. But the solution seems tedious and also gives me warning:

在此处输入图像描述

My current code looks like:

import React, {useContext, useEffect, useState, useRef} from 'react';
const ParentComponent = ({...props})=> {
const myRef = useRef();
const onClickFunction = () => {
        if(myRef.current) {
            myRef.current.childFunction();
        }
    }
return (
<ChildComponent ref = {myRef}/>
);
}

Child component

const ChildComponent = (({}, ref,{  actionButtons, ...props}) => {
const [childDataApi, setChildDataApi] = useState(null);

const childFunction = () => {
       //update childDataApi and pass it to parent
        console.log("inside refreshEntireGrid");
    }
});

Firstly, is there a better solution then trying to trigger childFunction from parent ? For this I am following this solution: Can't access child function from parent function with React Hooks I tried adding forward ref but that threw error as well. 在此处输入图像描述

I also found out that lifting the state up could be another solution as well. But I am not able to understand how to apply that solution in my case. Can someone please help me with this.

The warning says you were using forwardRef so with your snippet const ChildComponent = (({}, ref, { actionButtons, ...props }) => { .... } I'll assume this is a typo in your question and you were actually doing const ChildComponent = React.forwardRef(({}, ref,{ actionButtons, ...props }) => { .... }) .

The issue here, and the warning message points this out, is that you are passing a third argument to forwardRef when it only consumes two. It seems you destructure nothing from the first props argument. From what I can tell you should replace the first argument with the third where it looks like you are doing some props destructuring.

const ChildComponent = React.forwardRef(({ actionButtons, ...props }, ref) => { .... }

From here you should implement the useImperativeHandle hook to expose out the function from the child.

const ChildComponent = React.forwardRef(({ actionButtons, ...props }, ref) => {
  const [childDataApi, setChildDataApi] = useState(null);
  
  const childFunction = () => {
    // update childDataApi and pass it to parent
    console.log("inside refreshEntireGrid");
  }

  useImperativeHandle(ref, () => ({
    childFunction
  }));

  ...

  return ( ... );
});

In the parent component:

const ParentComponent = (props) => {
  const myRef = useRef();

  const onClickFunction = () => {
    myRef.current?.childFunction();
  }

  return (
    <ChildComponent ref={myRef}/>
  );
}

Something else you can try is to pass a prop to the child to indicate that the button has been clicked and use useEffect in the child component to do something when that value changes.

const Child = props => {
  useEffect(() => TriggeredFunc(), [props.buttonClicked]);

  const TriggeredFunc = () => {
    ...
  }

  return '...';
}

const Parent = () => {
  const [buttonClicked, setButtonClicked] = useState(0);

  const onClick = e => {
    setButtonClicked(buttonClicked++);
  }

  return <>
    <button onClick={onClick}>My Button</button>
    <Child buttonClicked={buttonClicked} />;
  </>

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM