Search code examples
reactjsreactstrap

Showing modal via method call in react app


In our react app (we use reactstrap), we've multiple pages from where a confirmation modal can be shown. We do not want to include the modal code in every page. Is there a way to do this programmatically by invoking a method?

We can use plain bootstrap modals directly in the public index.html and from the util method use dom selector and invoke the modal but want to avoid this. Any pointers on how to go about this?


Solution

  • Here's what we did.

    Alert Component:

        import React, { useState } from "react";
    import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
    
    const Alert = props => {
      const [modal, setModal] = useState(props.open ? props.open : true);
    
      const toggle = () => {
        setModal(!modal);
        if (props.cb) {
          props.cb();
        }
        if (props.reloadPage) {
          window.location.reload();
        }
      };
    
      return (
        <div>
          <Modal isOpen={modal} toggle={toggle}>
            <ModalHeader toggle={toggle}>{props.title}</ModalHeader>
            <ModalBody>{props.text}</ModalBody>
            <ModalFooter>
              <Button color="primary" onClick={toggle}>
                Ok
              </Button>
            </ModalFooter>
          </Modal>
        </div>
      );
    };
    
    export default Alert;
    

    Util.js:

    import React from "react";
    import ReactDOM from "react-dom";
    import Alert from "./Alert";
    
    const Util = {
      alert: (message, okCb, reload) => {
        ReactDOM.render(
          <Alert
            title="Done"
            text={message}
            cb={() => {
              ReactDOM.unmountComponentAtNode(
                document.getElementById("modalHolder")
              );
              if (okCb) {
                okCb();
              }
            }}
            reloadPage={reload}
          />,
          document.getElementById("modalHolder")
        );
      }
    };
    
    export default Util;
    

    In index.html we created a dom element:

    <div id="modalHolder"></div>
    

    So to invoke the modal imperatively, call:

    Util.alert("Data has been saved")