6

I'm new to React and to coding in general. I'm trying to render multiple modals in the same component, but they are all being rendered at the same time so that it looks like all the links are rendering the text in the last modal.
Here's where the state is set:

class Header extends React.Component {
  constructor () {
    super();
    this.state = {open:false}
    this.openModal = this.openModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
    this.handleModalChangeEnter = this.handleModalChange.bind(this, true);
    this.handleModalChangeLogin = this.handleModalChange.bind(this, false);
  }
  openModal () {
    this.setState({open: true}); }
  closeModal () {
    this.setState({open: false}); }
  render() {

And here's the modal construction:

return (
    <header style={home}>

    <div style={hello}>
      <img style={logo} src='public/ycHEAD.png'/>
      <p style={slogan}>One Calendar for All of Yerevan's Tech Events</p>
    </div>

    <div style={subContainer}>
      <ul style={modalDirectory}>

        <Button onClick={this.openModal}
                style={openButton}>
          <li><a style={tabs}>Enter
              </a></li>
        </button>
        <Modal style={modalCont}
               isOpen={this.state.open}>
              <button onClick={this.closeModal}
                      style={xButton}>x</button>
        </Modal>

        <button onClick={this.openModal} 
                style={openButton}>
          <li><a style={tabs}>Login
              </a></li>
        </button>
        <Modal style={modalCont}
               isOpen={this.state.open}>
          <p>Account</p>
          <button onClick={this.closeModal}
                  style={xButton}>x</button>
        </Modal> 

Should there be a value in the empty parentheses -> openModal() & closeModal() ?

Vianka Lemus
  • 109
  • 1
  • 1
  • 7

3 Answers3

4

A friend helped me out with this one. The top half of code remains the same, what changes is in the modal construction (some really helpful aesthetic changes were also made to the 'html'):

return (
    <header style={home}>      
    <div style={hello}>
        <img style={logo} src='public/ycHEAD.png'/>
        <p style={slogan}>One Calendar for All of Yerevan's Tech Events</p>
      </div>

      <div style={subContainer}>
        <ul style={modalDirectory}>

          <li style={tabs}>
            <button
              onClick={() => this.openModal('login')}
              style={openButton}>
              Enter
            </button>
          </li>

          <li style={tabs}>
            <button
              onClick={() => this.openModal('calendar')}
              style={openButton}>
              Calendar
            </button>
          </li>

          <li style={tabs}>
            <button
              onClick={() => this.openModal('team')}
              style={openButton}>
              Meet Us
            </button>
          </li>

        </ul>
      </div>


      <Modal
        style={modalCont}
        isOpen={this.state.activeModal === 'login'}>
        <p>1!</p>
          <button onClick={this.closeModal}
            style={xButton}>x</button>
      </Modal>

      <Modal
        style={modalCont}
        isOpen={this.state.activeModal === 'calendar'}>
        <p>2!</p>
          <button onClick={this.closeModal}
            style={xButton}>x</button>
      </Modal>

      <Modal
        style={modalCont}
        isOpen={this.state.activeModal === 'team'}>
        <p>3!</p>
          <button onClick={this.closeModal}
            style={xButton}>x</button>
      </Modal>

     </header>

If anyone else can provide a thorough explanation, please do so! Also, there is another way to do this using 'bind', but I don't know how.

Vianka Lemus
  • 109
  • 1
  • 1
  • 7
1

I have created similar approach but more detailed model for those who need this solution when using "react-modal". It's not clear in question above if react-modal was used or not because import section is missing, but seems to have references to it. For those who are looking for solution using react-modal to display multiple modals in same component, so here is solution and demo :

import React from "react";
import Modal from "react-modal";

class MutipleButtonsWithModalInSameComponent  extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        showModal: false,
        activeModal: "",
      };
      this.handleOpenModal = this.handleOpenModal.bind(this);
      this.handleCloseModal = this.handleCloseModal.bind(this);
    }
  
    handleOpenModal(val) {
      this.setState({ activeModal: val });
      this.setState({ showModal: true });
    }
  
    handleCloseModal() {
      this.setState({ showModal: false });
      this.setState({ showModal: "" });
    }
    render() {
      return(
        <>
        {/* {'one item with modal link -login'} */}
        <div className="icon">
            <a
              className="button"
              onClick={() => this.handleOpenModal("login")}
            >
              login (modal popup)
            </a>
            <Modal
              isOpen={
                this.state.showModal &&
                this.state.activeModal === "login"
              }
              contentLabel="login Modal"
            >
              <div className="content">
                <button className="close" onClick={this.handleCloseModal}>X</button>
                <p>login content in here</p>
              </div>

            </Modal>
        </div>
        {/* {'another item with modal link calendar, add more by mutiplying this below'} */}
        <div className="icon">
            <a
              className="button"
              onClick={() => this.handleOpenModal("calendar")}
            >
              calendar (modal popup)
            </a>
            <Modal
              isOpen={
                this.state.showModal &&
                this.state.activeModal === "calendar"
              }
              contentLabel="calendar Modal"
            >
              <div className="content">
                <button className="close" onClick={this.handleCloseModal}>X</button>
                <p>calendar content in here...</p>
              </div>

            </Modal>
        </div>

        {/* {'another item with modal link team, add more by mutiplying this below'} */}
        <div className="icon">
            <a
              className="button"
              onClick={() => this.handleOpenModal("team")}
            >
              team (modal popup)
            </a>
            <Modal
              isOpen={
                this.state.showModal &&
                this.state.activeModal === "team"
              }
              contentLabel="team Modal"
            >
              <div className="content">
                <button className="close" onClick={this.handleCloseModal}>X</button>
                <p>team content in here...</p>
              </div>

            </Modal>
        </div>

        </>
      )
      
    }
}
export default MutipleButtonsWithModalInSameComponent;

Here is a stackblitz link or demo

StefaDesign
  • 929
  • 10
  • 19
-1

You can do it in two ways.
1) Simple but doesn't scale: Maintain different state variables and functions for each Modal. i.e.,

this.state = {openModal1:false, openModal2:false}
this.openModal1 = this.openModal1.bind(this);
this.closeModal1 = this.closeModal1.bind(this);
this.openModal2 = this.openModal2.bind(this);
this.closeModal2 = this.closeModal2.bind(this); 

As we can see, the problem with this is redundancy of the code.

2) Use functions to eliminate redundancy: Maintain a function to change the content of the modal.

class Header extends React.Component {
  constructor () {
    super();
    this.state = {open:false, ModalContent:''}
    this.openModal = this.openModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
    this.handleModalChangeEnter = this.handleModalChange.bind(this);
    this.handleModalChangeLogin = this.handleModalChange.bind(this);
  }
  openModal () {
    this.setState({open: true}); }
  closeModal () {
    this.setState({open: false}); }
  handleModalChange1() {
    this.setState({ ModalContent : '<h1>Modal1 Content</h1>' 
  }
  handleModalChange2() {
    this.setState({ ModalContent : '<h1>Modal2 Content</h1>' 
  }
  render() {

Modal Construction Should be :

return (
<header style={home}>

<div style={hello}>
  <img style={logo} src='public/ycHEAD.png'/>
  <p style={slogan}>One Calendar for All of Yerevan's Tech Events</p>
</div>

<div style={subContainer}>
  <ul style={modalDirectory}>

    <button onClick={this.handleModalChange1}
            style={openButton}>
      <li><a style={tabs}>Enter
          </a></li>
    </button>
    <button onClick={this.handleModalChange2} 
            style={openButton}>
      <li><a style={tabs}>Login
          </a></li>
    </button>
    <Modal style={modalCont}
           isOpen={this.state.open}>
      <div dangerouslySetInnerHTML={{__html: this.state.ModalContent}} />
      <button onClick={this.closeModal}
              style={xButton}>x</button>
    </Modal> 
Anon
  • 129
  • 1
  • 9