可重用的模态组件反应打字稿

时间:2020-06-23 15:20:43

标签: reactjs typescript bootstrap-4 bootstrap-modal reactstrap

我有一个带有按钮的组件,就像这样-

<Button variant="primary" disabled={checkAccepted} onClick={openModal}>Send</Button>

我希望此按钮在激活时能够在单击时打开一个模式。我不确定如何执行此操作,并且一直在搞乱道具,但似乎无法弄清楚。我还希望模式可重用,以便任何内容都可以在模式主体中传递。我在想如何从我的openModal函数中打开模式? 我试图像这样退回它-

const openModal = () => {

return (
            <Modal>
                <ModalBody>*Pass in swappable content here*</ModalBody>
            </Modal>
        )
}

但这似乎不起作用。我确定我缺少什么。

2 个答案:

答案 0 :(得分:1)

您应该将触发模态的函数作为prop传递给<Button />组件。然后,您要在组件中添加onClick事件。您不能将onClick事件设置为<Button />。它将把onClick视为传递给<Button />的道具。在<Button />中,您可以将onClick事件设置为实际的<button>元素,并使用作为该事件的prop传入的函数。

您可以使用状态来跟踪单击模式按钮的时间。您的函数看起来像:(我在这里使用基于类的组件,但是您可以对功能组件执行相同的操作)

buttonClickedHandler = () => {
    this.setState({isModalButtonClicked: !this.state.isModalButtonClicked});
}

然后,您可以设置Modal组件,

<Modal isShow={this.state.isModalButtonClicked} modalButton={this.buttonClickedHandler}>
   <div> ...set contents of modal</div>
</Modal>

<button onClick={this.buttonClickedHandler}>Show Modal</button>

因此,在Modal组件中,您可以具有以下内容:

<React.Fragment>
    <Backdrop showModal={this.props.isShow} clicked={this.props.modalButton}/>
    {this.props.children}
</React.Fragment>

背景基本上是灰色背景。您还可以设置一个onClick事件,以在单击背景幕时监听。

答案 1 :(得分:1)

您不能从事件处理程序中返回组件。处理React中事件的方法几乎总是会更改应用程序的状态,从而触发重新渲染。在您的情况下,您需要跟踪模态的open状态。

这可以以受控方式(您自己跟踪打开状态并将其作为道具传递给<Modal>组件)或以不受控制的方式(<Modal>组件管理open状态本身)。第二种方法要求您提供呈现给您的Modal组件作为触发器的元素:

const MyModal = ({ children, trigger }) => {
  const [modal, setModal] = useState(false);
  const toggle = () => setModal(!modal);

  return (
    <div>
      {React.cloneElement(trigger, { onClick: toggle })}
      <Modal isOpen={modal} toggle={toggle}>
        <ModalBody>{children}</ModalBody>
      </Modal>
    </div>
  );
};

然后您可以像这样使用它:

<MyModal trigger={<Button variant="primary">Send</Button>}>
    <p>This is the content.</p>
</MyModal>

Edit quizzical-sunset-wzjfu

或者您可以以受控方式实施它。这更加灵活,因为它允许您在任何地方渲染触发元素:

const MyModal = ({ children, isOpen, toggle }) => (
  <div>
    <Modal isOpen={isOpen} toggle={toggle}>
      <ModalBody>{children}</ModalBody>
    </Modal>
  </div>
);

用法示例:

function App() {
  const [isOpen, setIsOpen] = useState(false);
  const toggle = () => setIsOpen(!isOpen);

  return (
    <div className="App">
      <Button variant="primary" onClick={toggle}>
        Send
      </Button>
      <MyModal isOpen={isOpen} toggle={toggle}>
        <p>This is the content.</p>
      </MyModal>
    </div>
  );
}

Edit keen-cray-7pf5k