React和React Hooks:在子级中使用onClick函数触发父包装组件的功能

问题描述

我有一个包装器组件,该组件根据其自身的状态(isDeleted)有条件地呈现其子级。基本上,我有一个“可删除的项目”组件,如果单击按钮将其删除,则该项目本身将从DOM中删除(通过返回一个空的ReactNode即 >)。问题是,我不知道如何将按钮单击事件(作为包装器的子项出现)传递给包装的组件本身:

export default function App() {
    return (
        <DeleteableItemComponent>
            {/* lots of other markup here */}
            <button onClick={triggerFunctionInsideDeletableItemComponent}>
        </DeleteableItemComponent>
    )
}

以及我的可删除项目组件的最基本版本:

export default function DeleteableItemComponent() {
    const [isDeleted,setIsDeleted] = useState(false);

    const functionIWantToFire = () => {
        // call API here to delete the item serverside; when successful,'delete' on frontend
        setIsDeleted(true)
    }

    if (isDeleted) {
        return <></>
    }

    return <>{children}</>
}

非常简单,我只想从按钮functionIWantToFire回调中调用onClick

如何通过钩子正确完成此操作?我曾考虑过使用上下文API,但从未见过它用于触发函数触发,仅用于设置值,在这种情况下,我想触发事件本身,而不是将特定值传递给包装器组件。我也不能仅通过传递布尔属性来正确地做到这一点,因为那样的话我只能设置一次,即从falsetrue

解决方法

您可以使用React.cloneElement API将道具传递给您的孩子,而使用React.children.map对其进行遍历。

React.Children.map(children,(child) => {
   return React.cloneElement(child,{ /* .. props here */ });
});

一个简单的例子就是。 您可以查看示例here


function App() {
  return (
   <Delete>
      <Child1 />
      <Child2 />
   </Delete>
  );
}

function Delete({ children }) {
  const [clicked,setClicked] = React.useState(0);

  const inc = () => setClicked(clicked + 1);
  const dec = () => setClicked(clicked - 1);

  return React.Children.map(children,(child) => {
    return React.cloneElement(child,{ inc,clicked,dec });
  });
}


function Child1(props) {
  return ( 
    <div>
      <p>{props.clicked}</p>
      <button onClick={props.inc}>Inc</button>
    </div>
  )
}

function Child2(props) {
  return ( 
    <div>
      <button onClick={props.dec}>Dec</button>
    </div>
  )
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...