Matt
Matt

Reputation: 674

Bootstrap based Modal is not appearing in React / Next JS application

I have been trying to add a modal to my site for a while now but no matter how much I tried, examples I followed, it just doesn't show up. I am using React with Next JS

I tried this and this and this but for some reason I am unable to make modal appear on the screen. Additionally, I deleted and reinstalled my node_modules folder and yarn.lock but that didn't make a difference either. Here are my steps:

  1. Grabbed a sample modal code from bootstrap components from https://getbootstrap.com/docs/4.4/components/modal/
  2. Created a Modal.js file in src/components
  3. Referenced that in index.js.

Result: I see the "launch demo modal" button but when I click, nothing happens. No error, nothing. I tried in both google chrome and safari and the outcome are the same. enter image description here

Here is my Modal.js component:

import React from "react";

const Modal = () => {
  console.log("is this being called?");
  return (
    <div>
      <button
        type="button"
        className="btn btn-primary"
        data-toggle="modal"
        data-target="#exampleModal"
      >
        Launch demo modal
      </button>

      <div
        className="modal fade"
        id="exampleModal"
        tabIndex="-1"
        role="dialog"
        aria-labelledby="exampleModalLabel"
        aria-hidden="true"
      >
        <div className="modal-dialog" role="document">
          <div className="modal-content">
            <div className="modal-header">
              <h5 className="modal-title" id="exampleModalLabel">
                Modal title
              </h5>
              <button
                type="button"
                className="close"
                data-dismiss="modal"
                aria-label="Close"
              >
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            <div className="modal-body">...</div>
            <div className="modal-footer">
              <button
                type="button"
                className="btn btn-secondary"
                data-dismiss="modal"
              >
                Close
              </button>
              <button type="button" className="btn btn-primary">
                Save changes
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Modal;

How I call it in index.js

import Modal from "../src/components/Modal";

const Index = ({ posts }) => {

 return (
    <Layout>
      <Navigation />
      <head>
      ....
      <Modal />
.....
)

Scripts referenced in index.html

   <script src="js/jquery/jquery.min.js"></script>
    <script src="js/popper/popper.min.js"></script>
    <!-- <script src="js/bootstrap/bootstrap.min.js"></script> -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    />

and Package.json

{
  "name": "testapp",
  "version": "1.0.0",
  "private": true,
  "engines": {
    "node": "12.2.0",
    "npm": "6.4.1",
    "yarn": "1.13.0"
  },
  "dependencies": {
    "@sendgrid/contact-importer": "^6.5.1",
    "@sendgrid/mail": "^6.5.1",
    "@zeit/next-css": "^1.0.1",
    "@zeit/next-sass": "^1.0.1",
    "body-parser": "^1.19.0",
    "bootstrap": "^4.4.1",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "isomorphic-unfetch": "^3.0.0",
    "next": "^9.1.4",
    "next-images": "^1.2.0",
    "node-sass": "^4.13.1",
    "raw-loader": "^4.0.0",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-ga": "^2.7.0",
    "react-markdown": "^4.2.2",
    "react-scripts": "3.2.0"
  },
  "scripts": {
    "dev": "node server/index",
    "build": "next build",
    "start": "next start -p $PORT"
  },
  "eslintConfig": {
    "extends": "react-app"
  }
}

Thanks for the help.

PS. Bootstrap styling does work only modal doesn't work. For example: <div className="col-md-6 my-auto"> works just fine. fors just fine.

Edit 1: I included to index.html

        <script src="js/jquery/jquery.min.js"></script>
        <script src="js/popper/popper.min.js"></script>
        <script src="js/bootstrap/bootstrap.min.js"></script>

and in the index.js

import $ from 'jquery'; 
                <button
                  type="button"
                  className="btn btn-primary"
                  onClick={() => $("#exampleModal").modal("show")}
                >
                  <Modal />
                </button>

Then I get the following error: enter image description here

Edit 2:

Deleted jquery import from index.js and ran $("#exampleModal").modal("show") in the developer console I get modal is not a function error now

enter image description here

Edit 3: So I added "reactstrap" and used one of the modals that mentioned here: https://reactstrap.github.io/components/modals/ Then in my index file I added this as part of a button just like in below:

   <button
    className="btn btn-primary"
    onClick={showConfirmationResult}
    >
    Submit
    <ModalExample isOpen={false} toggle={true} />
    </button>

and only then it worked but this is not ideal. I would like to trigger the modal based on a button click so I tried this:

 const showConfirmationResult = () => {
    return <ModalExample isOpen={false} toggle={true} />;
  };

But this doesn't work and I am not sure why.

Thanks for the help.

Upvotes: 2

Views: 5150

Answers (1)

Subin Sebastian
Subin Sebastian

Reputation: 10997

data-target and data-toggle based approach for firing modal won't work because your dom is dynamically created by react. This means your bootstrap javascript has finished running even before that button is rendered by react. So instead you should trigger it using the javascript approach https://getbootstrap.com/docs/4.4/components/modal/#via-javascript

Change your button to something like this.

  <button
    type="button"
    className="btn btn-primary"
    onClick={()=> $('#exampleModal').modal('show')}
  >
    Launch demo modal
  </button>

Upvotes: 3

Related Questions