当我在React中按下按钮时,如何使其仅显示特定的模态?

时间:2019-10-28 13:13:54

标签: javascript reactjs

当前正在尝试在React中创建模态,并希望创建一个网格,其中“按钮1”显示“模态1”,“按钮2”显示“模态2”等。 当我按下按钮以显示模式时,它同时显示模式1和模式2。如何设置它,以便按钮1仅打开模式1?

这是我的App.js:

import React from 'react';
import './main.css';
import Modal from './components/Modal/modal';

class App extends React.Component {
  state = {
    show: false
  };

  showModal = x => {
    this.setState({
      show: !this.state.show
    });
  };

  render() {
    return (
      <div>
        <div className="button-container">
          <button className="toggle-button" onClick={x => {
            this.showModal(x);
          }}>Show yourself Modal!</button>
        </div>
        <Modal onClose={this.showModal} show={this.state.show} title="Test modal 1" id="1">Lorem ipsum</Modal>
        <Modal onClose={this.showModal} show={this.state.show} title="Test modal 2" id="2">I am a different modal</Modal>
      </div>
    );
  }
}

export default App;

这是我的modal.js组件:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './modal.css';

export default class Modal extends Component {
    onClose = x => {
        this.props.onClose && this.props.onClose(x);
    };

    render() {
        if(!this.props.show) {
            return null;
        }

        return (
            <div className="modal-wrapper">
                <h2 className="modal-header">{this.props.title}</h2>
                <div>{this.props.children}</div>
                <div>
                    <button className="modal-close" onClick={this.onClose}></button>
                </div>
            </div>
        )
    }
}

Modal.propTypes = {
    onClose: PropTypes.func.isRequired,
    show: PropTypes.bool.isRequired
};

3 个答案:

答案 0 :(得分:2)

最简单的方法是在状态中添加第二个键,这样您就可以独立管理两个模式。

class App extends React.Component {
  state = {
    show1: false,
    show2: false
  };

然后将您的change函数变成一个curried函数,该函数接受一个参数来更新状态的正确部分。为了使用变量来访问对象键,我们需要像这样的数组来访问它:

  showModal = (modal) => (e) => {
    this.setState({
      [modal]: !this.state[modal]
    });
  };

然后像这样使用它:

  render() {
    return (
      <div>
        <div className="button-container">
          <button className="toggle-button" onClick={this.showModal('show1')}>Show yourself Modal 1!</button>
          <button className="toggle-button" onClick={this.showModal('show2')}>Show yourself Modal 2!</button>
        </div>
        <Modal onClose={this.showModal('show1')} show={this.state.show1} title="Test modal 1" id="1">Lorem ipsum</Modal>
        <Modal onClose={this.showModal('show2')} show={this.state.show2} title="Test modal 2" id="2">I am a different modal</Modal>
      </div>
    );
  }
}

答案 1 :(得分:1)

此刻,您什么状态都没说出要显示的模态。您正在使用this.state.show来控制两个模态的可见性。

您可以在App组件中引入state属性,该属性用于选择要显示的模式。例如,传入modalId或类似的点击处理程序。 (免责声明:未经测试的语法,但原理是正确的!)

所以您的状态可能如下所示:

state = {
  [
    { 
      id: 1,
      show: false
    },
    { 
      id: 2,
      show: false
    },
  ]
}

然后,在您的点击处理程序中,您需要传递要显示/隐藏的模式ID。您需要根据用户界面中的内容进行确定。

showModal(id) => {
  this.setState({
    [id]: !this.state[id].show
  })
}

答案 2 :(得分:1)

如果每个模态都需要Button并用其控制其行为,那么您可以通过执行类似这样的操作来向 modal组件引入状态:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './modal.css';

export default class Modal extends Component {
    constructor(props) {
       super(props);
       this.state = {
         showModal: false,
       }
    }   

    toggleShow = () => {
        const { showModal } = this.state;
        this.setState({showModal: !showModal})
    };

    render() {
        const { showModal } = this.state;        
        return (
            <div className="modal-wrapper">
                { showModal &&
                <div>
                    <h2 className="modal-header">{this.props.title}</h2>
                    <div>{this.props.children}</div>
                </div>
                }
                <div>
                    <button className="modal-close" onClick={() => this.toggleShow()}>{this.props.btnText}</button>
                </div>
            </div>
        )
    }
}

可以进一步构建以更改默认行为。这应该清除您的App.js代码。