-2

I am making an app using React framework.

So the problem I have here is that I want to execute this JS code in React. It is basically supposed to dynamically show and hide the <div>. Here is the code in the <script> tag which I want to run using React:

<script>
  var modal = document.getElementById("myModal");

  var btn = document.getElementById("myBtn");

  var span = document.getElementsByClassName("close")[0];

  btn.onclick = function() {
    modal.style.display = "block";
  }

  span.onclick = function() {
    modal.style.display = "none";
  }
</script>

And here is the css -

body {font-family: Arial, Helvetica, sans-serif;}

/* The Modal (background) */
.modal {
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  padding-top: 100px; /* Location of the box */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0,0,0); /* Fallback color */
  background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}

/* Modal Content */
.modal-content {
  background-color: #fefefe;
  margin: auto;
  padding: 20px;
  border: 1px solid #888;
  width: 80%;
}

/* The Close Button */
.close {
  color: #aaaaaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: #000;
  text-decoration: none;
  cursor: pointer;
}

And HTML -


<h2>Modal Example</h2>

<!-- Trigger/Open The Modal -->
<button id="myBtn">Open Modal</button>

<!-- The Modal -->
<div id="myModal" class="modal">

  <!-- Modal content -->
  <div class="modal-content">
    <span class="close">&times;</span>
    <p>Some text in the Modal..</p>
  </div>

</div>

I saw in many tutorials that the componentDidMount helps. But it is not working. Also, I find that componentDidMount is quite complicated. So is there an alternative way to run this JS code in React?

Alexander Nied
  • 12,804
  • 4
  • 25
  • 45
Professor
  • 1
  • 1
  • 3
    There's really no reason to keep this as direct DOM manipulation. Rewrite it as a state and a conditional operator in the JSX. – Quentin May 19 '22 at 13:32
  • Sorry, I don't understand you. Can you please answer with the code? – Professor May 19 '22 at 13:33
  • You can use an aerial function in the onClick() to run JS code, although I don't recommend using this – Python May 19 '22 at 13:35
  • 1
    OK, You have javascript, You have css, You have html. But You have no react here. You can just host plain old html page with everything (html/css/js) inside, and it will do the job – 83lynx May 19 '22 at 13:35
  • When editing your question you should pay attention to if and what changes someone else already does, so that you won't revert it. – t.niese May 19 '22 at 13:35
  • 2
    What Quentin is saying is that you are implementing a common antipattern seen by new learners of React or other MV* frameworks. When using MV* frameworks, the paradigm is: 1) Create a data model, 2) Create a view, 3) Bind the data model to the view, 4) Update the data model, which will cause an "automatic" update to the bound view. You should never be doing imperative, direct DOM manipulation-- it fundamentally is not how React is intended to be used, and will cause you pain. I recommend starting with a tutorial, or looking at how React Bootstrap manages modals. Good luck, and happy coding! – Alexander Nied May 19 '22 at 13:36
  • I am telling that I want to run this Javascript code in react – Professor May 19 '22 at 13:36
  • 3
    You **should not** run this JavaScript code in React-- doing direct DOM manipulation in an MV* library is almost always an antipattern. – Alexander Nied May 19 '22 at 13:36
  • 3
    @Professor — And we're telling you that doing so is a bad idea and you should learn how to solve the problem the React Way instead of trying to cram the 1990s way into React. – Quentin May 19 '22 at 13:37
  • This particular problem is an *excellent* beginner level problem to use to learn how to do things the React Way. – Quentin May 19 '22 at 13:38
  • Uhh, ok, I guess my question backfired on me, – Professor May 19 '22 at 13:38
  • I would recommend looking at [this SO answer that provides a more comprehensive explanation of why not to do direct DOM manipulation in MV* frameworks](https://stackoverflow.com/a/51304632/6831341). – Alexander Nied May 19 '22 at 13:40
  • https://stackoverflow.com/questions/24502898/show-or-hide-element-in-react – Quentin May 19 '22 at 13:43
  • I guess I will do it this way, thanks – Professor May 19 '22 at 13:44

1 Answers1

0

Ok, this should get You started. Your plain html/js transforms approximately to this. (css left as is)

class MyModalApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showModal: false};
    this.openModal = this.openModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
  }

  openModal() {
    this.setState({showModal: true});
  }

  closeModal() {
    this.setState({showModal: false});
  }

  render() {
    const style= this.state.showModal ? {display: "block"} : {display: "none"};
    return (
      <div>
        <h2>Modal Example</h2>

        {/* <!-- Trigger/Open The Modal --> */}
        <button id="myBtn" onClick={() => this.openModal()}>Open Modal</button>

        {/* <!-- The Modal --> */}
        <div id="myModal" class="modal" style={style}>

          {/* <!-- Modal content --> */}
          <div class="modal-content">
             <span class="close" onClick={() => this.closeModal()}>&times;</span>
             <p>Some text in the Modal..</p>
          </div>

        </div>
      </div>
    );
  }
}

ReactDOM.render(
  <MyModalApp />,
  document.getElementById('root')
);
body {font-family: Arial, Helvetica, sans-serif;}

/* The Modal (background) */
.modal {
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  padding-top: 100px; /* Location of the box */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0,0,0); /* Fallback color */
  background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}

/* Modal Content */
.modal-content {
  background-color: #fefefe;
  margin: auto;
  padding: 20px;
  border: 1px solid #888;
  width: 80%;
}

/* The Close Button */
.close {
  color: #aaaaaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: #000;
  text-decoration: none;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Alexander Nied
  • 12,804
  • 4
  • 25
  • 45
83lynx
  • 111
  • 5
  • 1
    While the underlying approach was correct, your code had some issues that prevented it from executing. I have updated the code into a functioning snippet that runs a working demo. – Alexander Nied May 19 '22 at 14:08