我有一个包装器组件,它根据自己的状态(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}</>
}
简单地说,我只想从按钮onClick
回调调用functionIWantToFire
。
如何通过挂钩正确完成此操作?我曾考虑过使用上下文API,但我从未见过它用于触发函数触发,仅用于设置值,在这种情况下,我希望触发事件本身,而不是将特定值传递给包装组件。我也不能通过传递布尔道具来正确地完成它,因为那样我只能设置一次,即从false
到true
。
您可以使用React.cloneElement
API将道具传递给您的孩子,同时使用React.children.map
对其进行迭代。
React.Children.map(children, (child) => {
return React.cloneElement(child, { /* .. props 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>
)
}