当前位置: 首页 > 知识库问答 >
问题:

前端 - 封装 React 父组件 使子组件添加确认框?

谈旺
2024-05-14

需求 封装一个react中使用的组件(函数式组件)
这个父组件内部放一个button 组件当点击父组件的时候,先弹窗,
然后确定弹窗内容后,再执行子组件的按钮点击逻辑

父组件内容

const Show - ()=>{  const [open, setOpen] = useState(false)const click = ()=>{//当我点击父组件的时候就会触发子组件的点击事件setOpen(true)}return <div onClick={click}> <Modal open={open}             title={"当前操作可能存在风险"}             onOk={() => setOpen(false)}      >        <p>当前操作可能存在风险,确定继续操作</p>      </Modal>{children}</div>}

子组件

<Button onClick={}>点击我确认</Button>

在不改造子组件的情况下,可以实现么,请各位大佬指点/

共有2个答案

皇甫高阳
2024-05-14

这里采用 React.cloneElement结合ref转发。
子组件的肯定是需要修改的,只不过并非是破坏性的修改,只做新增。

const Show: React.FC<PropsWithChildren> = ({ children }) => {  const [open, setOpen] = useState(false)  const ref = useRef<{ emitChildrenClick: any }>(null);  const onClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent> | any) => {    //当我点击父组件的时候就会触发子组件的点击事件    setOpen(true)    ref.current?.emitChildrenClick?.();  }  return (    <div onClick={onClick}>      <Modal open={open}        title={"当前操作可能存在风险"}        onOk={() => setOpen(false)}      >        <p>当前操作可能存在风险,确定继续操作</p>      </Modal>      {React.cloneElement(children as React.ReactElement, { ref })}    </div>  )}const Button1 = forwardRef((props, ref) => {  function onClick(event: React.MouseEvent<HTMLElement, MouseEvent>) {    event?.stopPropagation?.(); // 阻止事件冒泡  }  useImperativeHandle(ref, () => ({    emitChildrenClick: onClick  }))  return (    <Button onClick={onClick}>      点击我确认    </Button>  )})
罗允晨
2024-05-14

要实现这个功能,你需要一个方法来处理子组件的点击事件,并且当弹窗被确认后才执行该事件。由于你不希望改造子组件,你可以通过props将点击事件传递给子组件,并在父组件中控制该事件的执行。

首先,在父组件中定义一个函数来处理子组件的点击事件,但这个函数默认不执行任何操作,直到弹窗被确认。然后,当弹窗被确认时,你可以调用这个处理函数。

这里是如何修改你的父组件以实现这个功能:

import React, { useState } from 'react';const Show = ({ children }) => {  const [open, setOpen] = useState(false);  const [isConfirmed, setIsConfirmed] = useState(false);  const handleChildClick = () => {    // 当子组件的点击事件被触发时,这里什么也不做    // 等待弹窗被确认  };  const handleModalOk = () => {    setOpen(false);    setIsConfirmed(true);        // 在这里调用子组件应该执行的逻辑    // 假设子组件的点击事件是通过 props 传递进来的    // 你可以在这里模拟调用子组件的点击事件    // 但实际情况下,你需要根据实际情况来决定如何执行子组件的逻辑    // 例如,你可以通过回调函数或者状态管理库来执行子组件的逻辑  };  const handleClick = () => {    setOpen(true);    setIsConfirmed(false);  };  // 这里假设 children 中有一个 Button 组件,并且它的 onClick 属性可以通过 props 来设置  const childWithProps = React.Children.map(children, child => {    if (React.isValidElement(child) && child.type === Button) {      // 给子组件的 Button 传递一个处理函数,这个函数会在弹窗被确认后执行      return React.cloneElement(child, {        onClick: () => {          handleChildClick(); // 触发子组件的点击事件,但暂时不执行        },        disabled: !isConfirmed, // 当未确认时,禁用按钮以防止重复点击      });    }    return child;  });  return (    <div onClick={handleClick}>      <Modal open={open} title={"当前操作可能存在风险"} onOk={handleModalOk}>        <p>当前操作可能存在风险,确定继续操作</p>      </Modal>      {childWithProps}    </div>  );};// 假设的 Button 组件const Button = ({ children, onClick, disabled }) => (  <button onClick={onClick} disabled={disabled}>    {children}  </button>);export default Show;

在上面的代码中,我添加了一个isConfirmed状态来追踪弹窗是否被确认。当点击父组件时,弹窗打开并且isConfirmed设置为false。如果子组件的按钮被点击,handleChildClick会被调用,但此时不会执行任何操作。只有当弹窗被确认(handleModalOk被调用)时,isConfirmed会被设置为true,此时你可以决定如何处理子组件的点击事件。

请注意,这里的关键点在于React.cloneElement,它允许你复制一个元素并传递新的props。在这个例子中,我们给子组件的Button传递了一个新的onClick处理函数和disabled属性。

此外,请注意,这个解决方案假设子组件是一个Button组件,并且你能够直接访问并修改它的props。如果子组件是一个复杂的组件树,你可能需要更复杂的逻辑来处理子组件的点击事件。此外,对于实际的应用,你可能需要考虑使用更健壮的状态管理方案(如Redux)来处理跨组件的交互。

 类似资料:
  • 诉求:react父组件某些值改变后,需要让子组件同步更新,但是这个过程不能让父组件重新渲染 请帮忙罗列下所有可能的方式

  • 问题内容: 我的目标是在页面/父组件上动态添加组件。 我从这样的一些基本示例模板开始: main.js: App.js: SampleComponent.js: 此处已安装到预写在模板中的节点上。但是,如果我需要向App组件中添加不确定数量的组件怎么办?显然,我不能将所有必需的 div都 坐在那里。 在阅读了一些教程之后,我仍然不了解如何动态创建组件并将其动态添加到父组件。有什么办法呢? 问题答案

  • 是在切换时需要添加和删除的类。 如果使用状态来处理类名,那么内容重新发送器…示例:在子组件中有一个ajax调用,当单击menubutton时,它会重新编辑页面并返回其主页。

  • 下面有一个子组件,我正在尝试更新父组件中的。我已经尝试了几个迭代,但没有运气。

  • 我是个新手,所以不要用任何非技术性的词语。我有一个父组件,它在单击按钮时有一个按钮元素,调用一个函数来创建一个新对象。我想要的是,当用户单击这个按钮时,子组件应该呈现在父按钮元素下面,每次单击按钮时,新对象应该作为道具传递给子组件,以便它可以在屏幕上显示它,但以前调用的子组件应该保留在屏幕上。 从React导入; 类父母组件扩展反应。PureComponent{ }

  • 问题内容: 我有两个组件: 父组件 ,我想从中更改子组件的状态: 和 子组件 : 我需要从父组件更改子组件的 打开 状态,还是单击父组件中的按钮时从父组件调用子组件的 toggleMenu() ? 问题答案: 状态应在父组件中进行管理。您可以通过添加属性将值传输到子组件。