如何在 React 的子组件中关闭从父组件打开的 MUI Modal。

huangapple go评论71阅读模式
英文:

How to close MUI Modal opened from parent component inside child component react

问题

我需要创建一个模态组件,它可以从父组件中打开并从模态组件本身关闭,使用React。

我在父组件中设置了状态,并将其作为属性传递给子模态组件:

const [modalIsOpen, setModalIsOpen] = useState(false);

const handleOpenFromParent = () => {
  setModalIsOpen(true);
}

const handleCloseFromChild = () => {
  setModalIsOpen(false);
}

<div
  className={`${styles.w_30} p-3 d-flex justify-content-center align-items-center flex-column`}
  onClick={handleOpenFromParent}
>
  <ModalPaymentMethods
    playerNickname={nickname}
    paymentDescription={paymentMethodsVisa}
    paymentLogo={<Icon icon='mdi:credit-card-outline' color={'#84c3d3'} style={{ fontSize: '150px' }} />}
    depositTimes={11}
    depositAmount={'€18.6k'}
    depositTimesLastSixMonths={9}
    depositQuantityLastSixMonths={'€12.7k'}
    paymentMethodNumber={4301165517084005}
    expiryMonth={'07'}
    expiryYear={'2017'}
    holderName={`${name + ' ' + lastName}`}
    billingAddress={address}
    modalIsOpen={modalIsOpen}
    handleCloseFromChild={handleCloseFromChild}
  />
</div>

我能够从父组件中打开模态,但是无法从子组件中关闭它。

我将回调handleCloseFromChild作为属性传递,以便在模态上将可见状态设回false,但它不起作用,modalIsOpen 始终保持为 true,从回调函数中永远不会设置为 false:

const ModalPaymentMethods = ({
  playerNickname,
  paymentDescription,
  paymentLogo,
  depositTimes,
  depositAmount,
  depositTimesLastSixMonths,
  depositQuantityLastSixMonths,
  paymentMethodNumber,
  expiryMonth,
  expiryYear,
  holderName,
  billingAddress,
  modalIsOpen,
  handleCloseFromChild
}) => {
  console.log(modalIsOpen);
  console.log(handleCloseFromChild);

  return (
    <div className={styles.ModalPaymentMethods}>
      <Modal
        open={modalIsOpen}
        onClose={handleCloseFromChild}
        aria-labelledby='modal-modal-title'
        aria-describedby='modal-modal-description'
      >
        test
      </Modal>
    </div>
  );
}
英文:

I need to build a modal component that is opened from a parent component and closed from the modal component itself in React.

I'm setting the state in the parent component and passed it down to the child modal component as props:

  const [modalIsOpen, setModalIsOpen] = useState(false)

  const handleOpenFromParent = () =&gt; {
    setModalIsOpen(true)
  }

  const handleCloseFromChild = () =&gt; {
    setModalIsOpen(false)
  }

and

      &lt;div
        className={`${styles.w_30} p-3 d-flex justify-content-center align-items-center flex-column`}
        onClick={handleOpenFromParent}
      &gt;
        &lt;ModalPaymentMethods
          playerNickname={nickname}
          paymentDescription={paymentMethodsVisa}
          paymentLogo={&lt;Icon icon=&#39;mdi:credit-card-outline&#39; color={&#39;#84c3d3&#39;} style={{ fontSize: &#39;150px&#39; }} /&gt;}
          depositTimes={11}
          depositAmount={&#39;€18.6k&#39;}
          depositTimesLastSixMonths={9}
          depositQuantityLastSixMonths={&#39;€12.7k&#39;}
          paymentMethodNumber={4301165517084005}
          expiryMonth={&#39;07&#39;}
          expiryYear={&#39;2017&#39;}
          holderName={`${name + &#39; &#39; + lastName}`}
          billingAddress={address}
          modalIsOpen={modalIsOpen}
          handleCloseFromChild={handleCloseFromChild}
        /&gt;
      &lt;/div&gt;

I have no problems in opening the modal from the parent, but I'm not managing to close it once opened, from the child component.

I'm passing a callback handleCloseFromChild as a prop to set the visibility state back to false on the modal but it's not working, modalIsOpen remains always true and is never set to false from the callback function:

const ModalPaymentMethods = ({
  playerNickname,
  paymentDescription,
  paymentLogo,
  depositTimes,
  depositAmount,
  depositTimesLastSixMonths,
  depositQuantityLastSixMonths,
  paymentMethodNumber,
  expiryMonth,
  expiryYear,
  holderName,
  billingAddress,
  modalIsOpen,
  handleCloseFromChild
}) =&gt; {
  console.log(modalIsOpen)
  console.log(handleCloseFromChild)

  return (
    &lt;div className={styles.ModalPaymentMethods}&gt;
      &lt;Modal
        open={modalIsOpen}
        onClose={handleCloseFromChild}
        aria-labelledby=&#39;modal-modal-title&#39;
        aria-describedby=&#39;modal-modal-description&#39;
      &gt;
       test
      &lt;/Modal&gt;
     &lt;/div&gt;
   )

答案1

得分: 4

原因是ModalPaymentMethods组件位于具有onClick事件的div元素内部。
只需尝试在handleOpenFromParenthandleCloseFromChild函数中都添加控制台日志,然后您可以找到问题。

您可以简单地通过使用stopPropagation方法解决这个问题。

const handleCloseFromChild = (e) => {
   e.stopPropagation();
   setModalIsOpen(false);
}
英文:

The reason is that ModalPaymentMethods component inside the div element which has onClick event.
Just try write console log on both handleOpenFromParent and handleCloseFromChild function, then you can find the problem.

You can simply solve that problem by using stopPropagation method.

const handleCloseFromChild = (e) =&gt; {
   e.stopPropagation();
   setModalIsOpen(false)
}

答案2

得分: 0

你应该像这样定义一个开启状态:

const [open, setOpen] = useState(false)

之后,定义一个处理它的函数:

const handleToggleModal = () => { setOpen((current) => !current) }

你应该将这个 handleToggleModal 函数作为 props 传递给子组件,并在需要关闭模态框的地方调用它。

open 状态被用作一个开关布尔值,用于关闭和打开模态框。

英文:

You should define a open state like this:
const [open,setOpen]=useState(false)

After that define a function to handle it:
const handleToggleModal=()=&gt;{setOpen((current)=&gt;!current)}

and you should pass this handleToggleModal function as props to the child component and call it everywhere you need to close the modal.

open state is used as a toggle boolean value to close and open the modal

huangapple
  • 本文由 发表于 2023年3月12日 19:32:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712825.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定