onClick 不会从子组件更新父状态

时间:2021-03-29 18:12:42

标签: reactjs

我正在尝试创建一个可以使用 Modal.js 本身内部的按钮在点击时关闭的模态(弹出)。为了实现这一点,我在 Parent.js 中创建了 useState 并将 closeModal 函数(它更新父的状态)传递到 Modal.js 中。道具;

无论出于何种原因,onClick 事件都不会更新 Parent 的状态(即使它设法触发从 props 接受的 closeModal 函数)。从 console.log 我可以看到 closeModal 函数正在运行,但 Parent.js 状态仍然没有改变,所以 Modal 没有关闭。 onMouseDownonChange 等其他事件可以正常工作,并且 Modal 已按预期关闭。

请您解释一下为什么它不适用于 onClick 以及这里发生了什么?

这里是下面的代码和一个沙箱:Sandbox

Parent.js

import { useState } from "react";
import Modal from "./Modal";

export default () => {
  const [modal, setModal] = useState({
    isShown: false,
    name: ""
  });
  const { isShown } = modal;

  const openModal = () => {
    setModal({ ...modal, isShown: true });
  };

  const closeModal = () => {
    setModal({ ...modal, isShown: false });
    console.log("Modal must be close!");
  };

  return (
    <div className="parent" onClick={openModal}>
      {isShown ? <Modal closeModal={closeModal} /> : null}
      <div className="message">Open Modal</div>
    </div>
  );
};

Modal.js

export default ({ closeModal }) => {
  return (
    <div className="modal">
      <button className="close" onClick={closeModal}>
        onClick
      </button>
      <button className="close" onMouseDown={closeModal}>
        onMouseDown
      </button>
      <input type="text" placeholder="onChange" onChange={closeModal} />
    </div>
  );
};

P.S.:我设法通过移动 onClick 打开 Parent.js 中的模式来完成这项工作,但我仍然不明白为什么它不起作用以及真正发生了什么。我假设 onClick 状态更新得如此之快,以至于目前它与旧状态相比似乎没有区别,因此它最终不会更新。但这只是我的猜测...

你能帮我澄清一下吗?

Parent.js

import { useState } from "react";
import Modal from "./Modal";

export default () => {
  const [modal, setModal] = useState({
    isShown: false,
    name: ""
  });
  const { isShown } = modal;

  const openModal = () => {
    setModal({ ...modal, isShown: true });
  };

  const closeModal = () => {
    setModal({ ...modal, isShown: false });
    console.log("Modal must be close!");
  };

  return (
    <div className="parent">
      {isShown ? <Modal closeModal={closeModal} /> : null}
      <div className="message" onClick={openModal}>Open Modal</div>
    </div>
  );
};

1 个答案:

答案 0 :(得分:0)

您需要停止点击事件传播。由于 Child div 与 Parent(它的按钮)重叠,两个事件都按顺序发生:

  • “关闭模态(在子/模态中)”

  • “打开模态(在父/按钮中)”

这就是它保持开放的原因。要修复它,请在 Modal(子)组件中使用 stopPropagation :

<button className="close" onClick={e => {
   e.stopPropagation()
   closeModal()
}}>

PS:我建议使用 this modal

相关问题