У вас отличное начало, но вы упускаете несколько вещей.Вам просто нужно сделать ваши компоненты более гибкими и многократно используемыми (см. Комментарии ниже).
Некоторые примечания: В приведенном ниже примере используется ES6 деструктурирование , ES6 Fat Arrow Функции , функция отображения , оператор расширения и функции обратного вызова .Кроме того, вы не можете обернуть кликабельный элемент (Modal
) внутри другого кликабельного элемента (div
).Самый внешний элемент (div
) будет обрабатываться только обработчиком событий onClick
.
Рабочий пример (для простоты я не использую изображения, вместо этого яс использованием заполнителя example.png
заголовков, которые можно нажимать):
компонентов / модальные
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;