关闭 React 模态
Close React Modal
我在尝试弄清楚如何向我的模式中添加一个正常运行的关闭按钮时遇到了很多问题 - constructor/props 一直没有用,我不确定在 onClick= 之后放什么在按钮元素中。
class Modal extends React.Component {
// whenever component gets rendered to the screen we create a new div assigned to this.modalTarget
componentDidMount() {
this.modalTarget = document.createElement('div');
// add class name to modal target
this.modalTarget.className = 'modal';
// take the div we just created and append it to the body tag in doc
document.body.appendChild(this.modalTarget);
// call method _render
this._render();
}
// whenever the component's about to update we do another render
// this render makes sure that if we get a new set of components or children in the modal
// we're going to render those to the parent div as well
componentWillUpdate() {
this._render();
}
// clean up - whenever the component is about to unmount from the screen
// cleans up dom when the modal is removed from the component heirarchy
componentWillUnmount() {
// unmounts this.props.children
ReactDOM.unmountComponentAtNode(this.modalTarget);
document.body.removeChild(this.modalTarget);
}
_render() {
// take react dom library and render a div that contains this.props.children
// and render it into this.modalTarget
ReactDOM.render(
<Provider store= {store}>
<Router>
<div className="modal">
{this.props.children}
<button>Close</button>
</div>
</Router>
</Provider>,
this.modalTarget
您的模态窗口似乎已打开,这仅取决于它是否由父级呈现。除了一起重新构建此模式之外,实现您想要的唯一方法是传递某种 onClose 回调:
class Parent extends React.Component {
state = { isModalOpen: false };
render() {
return (<div>
// Stuff
{this.state.isModalOpen &&
<Modal onClose={() => this.setState({ isModalOpen: false })}/>
}
// Stuff
</div>);
}
}
在你的Modal
中:
<div className="modal">
{this.props.children}
<button onClick={this.props.onClose}>Close</button>
</div>
这里有几个问题。首先,远离直接操纵 DOM
。 React 使用虚拟 DOM
,因此您无需手动添加或删除 DOM
元素。 React 通过 render
方法自动处理这个 DOM
操作。
此外,您需要使用某种 state
(isOpen) 来控制此 Modal
。它可以通过 React 的本地状态或通过 Redux 的状态。无论哪种方式,都需要对其进行控制和比较。简而言之,如果它是打开的,则渲染 Modal
,如果它关闭,则渲染 null
.
此外,这个 Modal
组件可以构造为可重用。只需将它作为 child
添加到另一个有状态的 parent
组件,并包含任何 children
您想要在其中呈现的内容。
工作示例:
components/Example.js(父组件)
import React, { Component } from "react";
import Modal from "../Modal";
import "./styles.css";
class Example extends Component {
state = { isOpen: false };
handleOpenModal = () => {
this.setState({ isOpen: true });
};
handleCloseModal = () => {
this.setState({ isOpen: false });
};
render = () => (
<div className="example">
<h2>Simple Modal Example</h2>
<button
className="uk-button uk-button-primary uk-button-small"
onClick={this.handleOpenModal}
>
Open Modal
</button>
<Modal isOpen={this.state.isOpen} onCloseModal={this.handleCloseModal}>
<h1 className="title">Hello!</h1>
<p className="subtitle">There are two ways to close this modal</p>
<ul>
<li>Click outside of this modal in the grey overlay area.</li>
<li>Click the close button below.</li>
</ul>
<button
className="uk-button uk-button-danger uk-button-small"
onClick={this.handleCloseModal}
>
Close
</button>
</Modal>
</div>
);
}
export default Example;
components/Modal.js(子组件——它有很多更小的组件,为了可重用性和易于理解而分开——它们基本上很简单div
s 附有一些 styles
-- 见下面的注释)
import React from "react";
import PropTypes from "prop-types";
import BackgroundOverlay from "../BackgroundOverlay"; // grey background
import ClickHandler from "../ClickHandler"; // handles clicks outside of the modal
import Container from "../Container"; // contains the modal and background
import Content from "../Content"; // renders the "children" placed inside of <Modal>...</Modal>
import ModalContainer from "../ModalContainer"; // places the modal in the center of the page
// this is a ternary operator (shorthand for "if/else" -- if cond ? then : else)
// below can be read like: if isOpen is true, then return/render the modal, else return null
const Modal = ({ children, isOpen, onCloseModal }) =>
isOpen ? (
<Container>
<BackgroundOverlay />
<ModalContainer>
<ClickHandler isOpen={isOpen} closeModal={onCloseModal}>
<Content>{children}</Content>
</ClickHandler>
</ModalContainer>
</Container>
) : null;
// these proptype declarations are to ensure that passed down props are
// consistent and are defined as expected
Modal.propTypes = {
children: PropTypes.node.isRequired, // children must be a React node
isOpen: PropTypes.bool.isRequired, // isOpen must be a boolean
onCloseModal: PropTypes.func.isRequired // onCloseModal must be a function
};
export default Modal;
我在尝试弄清楚如何向我的模式中添加一个正常运行的关闭按钮时遇到了很多问题 - constructor/props 一直没有用,我不确定在 onClick= 之后放什么在按钮元素中。
class Modal extends React.Component {
// whenever component gets rendered to the screen we create a new div assigned to this.modalTarget
componentDidMount() {
this.modalTarget = document.createElement('div');
// add class name to modal target
this.modalTarget.className = 'modal';
// take the div we just created and append it to the body tag in doc
document.body.appendChild(this.modalTarget);
// call method _render
this._render();
}
// whenever the component's about to update we do another render
// this render makes sure that if we get a new set of components or children in the modal
// we're going to render those to the parent div as well
componentWillUpdate() {
this._render();
}
// clean up - whenever the component is about to unmount from the screen
// cleans up dom when the modal is removed from the component heirarchy
componentWillUnmount() {
// unmounts this.props.children
ReactDOM.unmountComponentAtNode(this.modalTarget);
document.body.removeChild(this.modalTarget);
}
_render() {
// take react dom library and render a div that contains this.props.children
// and render it into this.modalTarget
ReactDOM.render(
<Provider store= {store}>
<Router>
<div className="modal">
{this.props.children}
<button>Close</button>
</div>
</Router>
</Provider>,
this.modalTarget
您的模态窗口似乎已打开,这仅取决于它是否由父级呈现。除了一起重新构建此模式之外,实现您想要的唯一方法是传递某种 onClose 回调:
class Parent extends React.Component {
state = { isModalOpen: false };
render() {
return (<div>
// Stuff
{this.state.isModalOpen &&
<Modal onClose={() => this.setState({ isModalOpen: false })}/>
}
// Stuff
</div>);
}
}
在你的Modal
中:
<div className="modal">
{this.props.children}
<button onClick={this.props.onClose}>Close</button>
</div>
这里有几个问题。首先,远离直接操纵 DOM
。 React 使用虚拟 DOM
,因此您无需手动添加或删除 DOM
元素。 React 通过 render
方法自动处理这个 DOM
操作。
此外,您需要使用某种 state
(isOpen) 来控制此 Modal
。它可以通过 React 的本地状态或通过 Redux 的状态。无论哪种方式,都需要对其进行控制和比较。简而言之,如果它是打开的,则渲染 Modal
,如果它关闭,则渲染 null
.
此外,这个 Modal
组件可以构造为可重用。只需将它作为 child
添加到另一个有状态的 parent
组件,并包含任何 children
您想要在其中呈现的内容。
工作示例:
components/Example.js(父组件)
import React, { Component } from "react";
import Modal from "../Modal";
import "./styles.css";
class Example extends Component {
state = { isOpen: false };
handleOpenModal = () => {
this.setState({ isOpen: true });
};
handleCloseModal = () => {
this.setState({ isOpen: false });
};
render = () => (
<div className="example">
<h2>Simple Modal Example</h2>
<button
className="uk-button uk-button-primary uk-button-small"
onClick={this.handleOpenModal}
>
Open Modal
</button>
<Modal isOpen={this.state.isOpen} onCloseModal={this.handleCloseModal}>
<h1 className="title">Hello!</h1>
<p className="subtitle">There are two ways to close this modal</p>
<ul>
<li>Click outside of this modal in the grey overlay area.</li>
<li>Click the close button below.</li>
</ul>
<button
className="uk-button uk-button-danger uk-button-small"
onClick={this.handleCloseModal}
>
Close
</button>
</Modal>
</div>
);
}
export default Example;
components/Modal.js(子组件——它有很多更小的组件,为了可重用性和易于理解而分开——它们基本上很简单div
s 附有一些 styles
-- 见下面的注释)
import React from "react";
import PropTypes from "prop-types";
import BackgroundOverlay from "../BackgroundOverlay"; // grey background
import ClickHandler from "../ClickHandler"; // handles clicks outside of the modal
import Container from "../Container"; // contains the modal and background
import Content from "../Content"; // renders the "children" placed inside of <Modal>...</Modal>
import ModalContainer from "../ModalContainer"; // places the modal in the center of the page
// this is a ternary operator (shorthand for "if/else" -- if cond ? then : else)
// below can be read like: if isOpen is true, then return/render the modal, else return null
const Modal = ({ children, isOpen, onCloseModal }) =>
isOpen ? (
<Container>
<BackgroundOverlay />
<ModalContainer>
<ClickHandler isOpen={isOpen} closeModal={onCloseModal}>
<Content>{children}</Content>
</ClickHandler>
</ModalContainer>
</Container>
) : null;
// these proptype declarations are to ensure that passed down props are
// consistent and are defined as expected
Modal.propTypes = {
children: PropTypes.node.isRequired, // children must be a React node
isOpen: PropTypes.bool.isRequired, // isOpen must be a boolean
onCloseModal: PropTypes.func.isRequired // onCloseModal must be a function
};
export default Modal;