使用反应钩子从父组件触发子函数

AmC*_*ous 7 reactjs

我在父组件中有一些操作按钮。单击此类按钮之一时,我想触发子组件中的一个功能。目前,我正在尝试使用 useRef 钩子来实现它。但该解决方案似乎很乏味,并且还给了我警告:

在此输入图像描述

我当前的代码如下所示:

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}/>
);
}
Run Code Online (Sandbox Code Playgroud)

子组件

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

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

首先,是否有比尝试从父级触发 childFunction 更好的解决方案?为此,我遵循以下解决方案: Can't access child function fromparent function with React Hooks 我尝试添加前向引用,但这也引发了错误。 在此输入图像描述

我还发现提升状态也可能是另一种解决方案。但我无法理解如何在我的案例中应用该解决方案。有人可以帮我解决这个问题吗?

Dre*_*ese 17

警告说您forwardRef在代码片段中使用了 so ,const ChildComponent = (({}, ref, { actionButtons, ...props }) => { .... }我会认为这是您问题中的拼写错误,而您实际上正在这样做const ChildComponent = React.forwardRef(({}, ref,{ actionButtons, ...props }) => { .... })

这里的问题(警告消息指出了这一点)是,forwardRef当它只消耗两个参数时,您正在传递第三个参数。看来你从第一个参数中没有解构任何东西props。据我所知,你应该用第三个参数替换第一个参数,看起来你正在做一些道具解构。

const ChildComponent = React.forwardRef(({ actionButtons, ...props }, ref) => { .... }
Run Code Online (Sandbox Code Playgroud)

从这里开始,您应该实现useImperativeHandle钩子以从子级中公开该函数。

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 ( ... );
});
Run Code Online (Sandbox Code Playgroud)

在父组件中:

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

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

  return (
    <ChildComponent ref={myRef}/>
  );
}
Run Code Online (Sandbox Code Playgroud)


squ*_*man 6

您可以尝试的其他方法是将一个 prop 传递给子组件以指示该按钮已被单击,并useEffect在子组件中使用该 prop 在该值更改时执行某些操作。

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} />;
  </>

}
Run Code Online (Sandbox Code Playgroud)