Реагирует на рендеринг нескольких модалов в одном компоненте

#reactjs #ecmascript-6 #react-modal

#reactjs #ecmascript-6 #реагировать-модальный

Вопрос:

Я новичок в React и в кодировании в целом. Я пытаюсь отобразить несколько модалов в одном компоненте, но все они отображаются одновременно, так что похоже, что все ссылки отображают текст в последнем модальном.
Здесь задается состояние:

 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() {
  

И вот модальная конструкция:

 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> 
  

Должно ли быть значение в пустых круглых скобках -> openModal() amp; closeModal() ?

Ответ №1:

Друг помог мне с этим. Верхняя половина кода остается прежней, какие изменения внесены в модальную конструкцию (некоторые действительно полезные эстетические изменения были также внесены в «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>
  

Если кто-нибудь еще может предоставить подробное объяснение, пожалуйста, сделайте это! Кроме того, есть другой способ сделать это с помощью ‘bind’, но я не знаю как.

Ответ №2:

Я создал аналогичный подход, но более подробную модель для тех, кому нужно это решение при использовании «react-modal». В вопросе выше неясно, использовался ли react-modal или нет, потому что раздел импорта отсутствует, но, похоже, есть ссылки на него. Для тех, кто ищет решение с использованием react-modal для отображения нескольких модалов в одном компоненте, вот решение и демонстрация :

 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 amp;amp;
                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 amp;amp;
                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 amp;amp;
                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;
  

Вот ссылка на stackblitz или демонстрация

Ответ №3:

Вы можете сделать это двумя способами.
1) Простой, но не масштабируемый: поддерживайте разные переменные состояния и функции для каждого модала. т.е.,

 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); 
  

Как мы видим, проблема с этим заключается в избыточности кода.

2) Используйте функции для устранения избыточности: поддерживайте функцию для изменения содержимого модала.

 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() {
  

Модальная конструкция должна быть :

 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>