reactjs - 如何在 ReactJS 中使用多个对话框和渲染模式

标签 reactjs modal-dialog components material-ui

我无法弄清楚如何使用 Material UI 的对话框来渲染模态,在单击按钮时关闭它们,并使其单击不同的东西会显示不同的模态。

这是我从 Material UI 中获取的对话框组件

import React from 'react';
import Button from '@material-ui/core/Button';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';


class DialogBox extends React.Component {

  render() {
    return (
      <Dialog
      open={this.props.open}
      onClose={this.props.handleClose}
      aria-labelledby="alert-dialog-title"
      aria-describedby="alert-dialog-description"
    >
      <DialogTitle id="alert-dialog-title">{"Use Google's location service?"}</DialogTitle>
      <DialogContent>
        <DialogContentText id="alert-dialog-description">
          Let Google help apps determine location. This means sending anonymous location data to
          Google, even when no apps are running.
        </DialogContentText>
      </DialogContent>
      <DialogActions>
        <Button onClick={this.props.handleClose} color="primary">
          Okay
        </Button>
      </DialogActions>
    </Dialog>
    );
  }
}


export default DialogBox;

这是我在其中渲染对话框的页面,我在这里将其称为模态。如何做到这一点,以便我可以在对话框打开时关闭它,并且还可以单击不同的图片并让它打开一个包含不同文本的对话框?

import React,{Component} from "react";
import home from "./home.png";
import car from "./car.png";
import bed from "./bed.png";
import pet from "./pet.png";
import Dialog from "./Modal.js";

class Scenarios extends Component {
  constructor(){
    super();
    this.state = { open: false };
  }

  openModal = () =>{
    this.setState({ open: true });
  }

  handleClose = () => {
    this.setState({ open: false });
  };

  render() {
    return (
       <section className="App-scenarios">
        <h2> Quick Tips </h2>
        <p>Know What to Do in Different Scenarios during an Earthquake</p>
        <div className="scenario-group">

          <div className="scenario" onClick={this.openModal}>
            <img src={car}/>
          </div> 

          <div className="scenario" onClick={this.openModal}>
          <img src={home}/>
            <Dialog open={this.state.open} onClose={this.handleClose} title="Home" description="text" />
          </div>
          <div className="scenario" >
          <img src={bed}/>
          </div>
          

          <div className="scenario">
          <img src={pet}/>
          </div>
        </div>
      </section>
    );
    }
};

export default Scenarios;

最佳答案

您有一个良好的开端,但您缺少一些项目。您只需要使您的组件更加灵活和可重用(请参阅下面的评论)。

一些注意事项:下面的示例使用 ES6 destructuring , ES6 Fat Arrow Functionsmap functionspread operator ,和 callback functions 。此外,您不能将可点击元素 (Modal) 包装在另一个可点击元素 (div) 内。最外面的元素 (div) 将仅由 onClick 事件处理程序处理。

工作示例(为简单起见,我没有使用图像,而是使用可点击的占位符 example.png 标题):

Edit Reusable DialogBox

<小时/>

组件/模态

import React from "react";
import PropTypes from "prop-types";
import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogContentText,
  DialogTitle
} from "@material-ui/core";


// "Modal is a pure function that requires 4 parameters in order to display 
// the "<Modal />" component. This function would be the same as a traditional function:
// 
//   function Modal({ deconstructed parameters }) { 
//     return (
//       <Dialog>
//        ...
//      </Dialog>
//     )
//   }

const Modal = ({ description, onCloseModal, openModal, title }) => ( 
  <Dialog
    open={openModal}
    onClose={onCloseModal}
    aria-labelledby="alert-dialog-title"
    aria-describedby="alert-dialog-description"
  >
    <DialogTitle id="alert-dialog-title">{title}</DialogTitle>
    <DialogContent>
      <DialogContentText id="alert-dialog-description">
        {description}
      </DialogContentText>
    </DialogContent>
    <DialogActions>
      <Button onClick={onCloseModal} color="primary">
        Okay
      </Button>
    </DialogActions>
  </Dialog>
);

// PropTypes throws a warning if any of the 4 required params are
// missing! In addition, it ensures that props are consistent in name
// and declaration from parent component to child component.

Modal.propTypes = {
  description: PropTypes.string.isRequired,
  onCloseModal: PropTypes.func.isRequired,
  openModal: PropTypes.bool.isRequired,
  title: PropTypes.string.isRequired
};

export default Modal;

组件/场景

import React, { PureComponent } from "react";
import PropTypes from "prop-types";


// Scenario will be a PureComponent (stateless, but still a class component) 
// that will open the Modal component with a supplied "description" and 
// "title" via a parent callback function named "handleOpenModal"

class Scenario extends PureComponent {
  openModal = () => {
    const { description, handleOpenModal, title } = this.props;
    handleOpenModal({ description, title });
  };

  render = () => (
    <div className="scenario" onClick={this.openModal}>
      <h1>{this.props.imgSrc}</h1>
    </div>
  );
}

Scenario.propTypes = {
  description: PropTypes.string.isRequired,
  handleOpenModal: PropTypes.func.isRequired,
  imgSrc: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired
};

export default Scenario;

组件/场景

import React, { Component } from "react";
import Modal from "../Modal";
import Scenario from "../Scenario/";

// A scenarios variable of an array of objects -- makes it so we don't have to 
// repeat <Scenario title=".." description="..."imgSrc={...} handleOpenModal={..} /> 
// over and over, instead we map over these objects as "props" and spread
// them out inside of "Scenario" like so: <Scenario {...props} />, which 
// would be the same as:  
// <Scenario title={title} description={description} imgSrc={imgSrc} />

const scenarios = [
  {
    title: "Car",
    description: "This is a description for a car.",
    imgSrc: "car.png"
  },
  {
    title: "Home",
    description: "This is a description for a home.",
    imgSrc: "home.png"
  },
  {
    title: "Bed",
    description: "This is a description for a bed.",
    imgSrc: "bed.png"
  },
  {
    title: "Pet",
    description: "This is a description for a pet.",
    imgSrc: "pet.png"
  }
];

// Scenarios is a stateful class component that'll act as the parent 
// for its "Scenario" children. The children will update the parent via 
// "this.handleOpenModal". Meanwhile, "Modal" will sit inside the parent
// waiting for the parent state updates to affect how its rendered. The 
// Modal will close itself via the parent's "this.handleCloseModal"
// class method when the "Okay" button is clicked.

class Scenarios extends Component {
  state = { description: "", openModal: false, title: "" };

  handleOpenModal = ({ description, title }) => {
    this.setState({ description, openModal: true, title });
  };

  handleCloseModal = () => {
    this.setState({ openModal: false });
  };

  render = () => (
    <section className="App-scenarios">
      <h2> Quick Tips </h2>
      <p>Know What to Do in Different Scenarios during an Earthquake</p>
      <div className="scenario-group">
        {scenarios.map(props => (
          <Scenario
            {...props}
            key={props.title} // this is required for React to know that each "Scenario" that is returned by the "map" function is unique and must be handled as individual components (otherwise React will complain and throw a warning)
            handleOpenModal={this.handleOpenModal}
          />
        ))}
      </div>
      <Modal {...this.state} onCloseModal={this.handleCloseModal} />
    </section>
  );
}

export default Scenarios;

关于reactjs - 如何在 ReactJS 中使用多个对话框和渲染模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55202348/

相关文章:

javascript - JSX 中的 bool 复选框值不起作用

javascript - react 属性消失

php - 获取引导模式值并设置为文本字段

objective-c - cocoa 执行点击按钮等待下一个外部事件

delphi - 如何捕捉父控件调整大小的时刻?

javascript - 使用 React.JS 获取 API 数据问题

javascript - 由于react组件的key值出现错误但不知道如何更改

reactjs - 如何在 IE9 中运行 ES6 React 应用程序而不会出现错误

javascript - 如何改变模态内容(无需 Bootstrap )

forms - Joomla 2.5 - 组件开发 - 使用表单