触发函数以关闭 ReactJS 中的模态 window
Trigger a function to close a modal window in ReactJS
我正在使用 Gatsby 在 ReactJS 中创建我的投资组合部分,我在处理 KeyDown 时遇到了一些麻烦。
我的代码允许我检测何时按下 ESC 键,但我无法像对叠加层(onClick 事件)所做的那样触发关闭功能。
我有三个不同的文件:
modal.js
- 模态组件
project.js
- 项目组件
projets.js
- 项目页面
我创建了模式window,它将显示项目的详细信息。项目组件会显示所有的项目缩略图,最后项目页面会渲染项目组件。
也许我遗漏了什么。我会感谢你的帮助。
模态组件的代码如下:
modal.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Link } from 'gatsby-link'
import './modal.scss'
import MdClose from 'react-icons/lib/md/close'
export class Modal extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
this.initializeEscClosing();
}
initializeEscClosing() {
if (typeof window !== 'undefined') {
window.addEventListener('keydown', (e) => {
if (e.which == 27) {
//this.props.onClose
console.log('It\'s working')
}
});
}
}
render() {
// Render nothing if the "show" prop is false
if (!this.props.show) {
return null;
}
return (
<div className={`modal`}>
<div className={`modal__overlay`}
onClick={this.props.onClose}
onKeyDown = {
this.initializeEscClosing
}
tabIndex = "0"
>
</div>
<div className={`modal__container`}>
<div className={`modal__body`}>
<div className={`top`}>
<button onClick={this.props.onClose}><MdClose /></button>
</div>
<div className={`content`}>
{this.props.children}
</div>
</div>
</div>
</div>
)
}
}
Modal.propTypes = {
onClose: PropTypes.func.isRequired,
show: PropTypes.bool,
children: PropTypes.node
};
export default Modal
我注意到当我按下 ESC
时,该功能被触发了 3 次,因为我的 .json
文件中有 3 个项目。我该如何解决这个问题?
这是项目组件的代码:
project.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {Link} from 'gatsby-link'
import './project.scss'
import {LinkWebsite, ButtonProject} from '../../../components/atoms/button'
import {Modal } from '../modal'
export class Project extends Component {
constructor(props){
super(props)
this.state = {
opened:false
}
this._toggleModal = this._toggleModal.bind(this)
}
_toggleModal(){
this.setState({
opened: !this.state.opened
})
}
render(){
const { title, category, image, logo, children, website} = this.props
return(
<div className="project__container">
<div className="project__preview">
<button onClick={this._toggleModal}>
{logo ? <img src={logo.src} alt={title} /> : null}
<h2>{title} <span className="category">{category}</span></h2>
</button>
</div>
<div className="project__details">
<Modal
onClose={this._toggleModal}
show={this.state.opened}
>
{image ? <img src={image.src} alt={title} /> : null}
<h3>{title} <span className="category">{category}</span></h3>
{children}
{website ? <LinkWebsite link={website}>Voir le site</LinkWebsite> : null}
</Modal>
</div>
</div>
)
}
}
export default Project
Project.propTypes = {
title: PropTypes.string.isRequired,
category: PropTypes.string.isRequired,
image: PropTypes.shape({
src: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
}).isRequired,
logo: PropTypes.shape({
src: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
}).isRequired,
children: PropTypes.element.isRequired,
website: PropTypes.string,
};
Project.defaultProps = {
title: 'Nom du projet',
image: null,
logo: null,
children: 'Texte introductif du projet. Il fourni les éléments clés',
website: null,
};
这是项目页面的代码:
projets.js
import React, { Component } from 'react'
import Link from 'gatsby-link'
import { Project } from '../components/molecules/project'
const projectPage = ({ data }) => {
return(
<div>
<h1>Projets récents</h1>
<div className="projects__container">
{data.allProjectsJson.edges.map(({ node }, i) =>
(<Project
key={i}
title={node.title}
category={node.category}
image={{
src: node.image.childImageSharp.original.src,
alt: node.title,
}}
logo={{
src: node.logo.childImageSharp.original.src,
alt: node.title,
}}
website={node.website}
>
<p dangerouslySetInnerHTML={{ __html: node.description }} />
</Project>),
)}
</div>
</div>
)
}
export default projectPage
export const pageQuery = graphql`
query ProjectsQuery {
allProjectsJson {
edges {
node {
title
category
description
image {
childImageSharp {
original {
src
}
}
}
logo {
childImageSharp {
original {
src
}
}
}
website
}
}
}
}
`;
提前感谢您抽出宝贵时间提供帮助
祝你周五愉快,
亲切的问候,
马拉
你可以尝试使用箭头函数,我手头没有笔记本电脑,对此深表歉意,但你可以尝试这样的方法
// Modal component
...
onClick={()=> {this.props.onClose()}
// Project component
onClose={() => {console.log(‘might be triggered’); this.toggleModal()}}
使用箭头函数让你摆脱构造函数的绑定
我认为 initializeEscClosing() 函数中有些地方不完全正确。
为什么要在其中创建一个侦听器? onKeyDown 本身就是一个监听器。
尝试做这样的事情来触发事件。
<div onKeyDown = {event => this.keyDownHandler(event)}/>
event prop 包含有关键事件的所有信息,因此在处理它的函数中,您可以检查键是否正确并最终关闭模态
我正在使用 Gatsby 在 ReactJS 中创建我的投资组合部分,我在处理 KeyDown 时遇到了一些麻烦。 我的代码允许我检测何时按下 ESC 键,但我无法像对叠加层(onClick 事件)所做的那样触发关闭功能。 我有三个不同的文件:
modal.js
- 模态组件project.js
- 项目组件projets.js
- 项目页面
我创建了模式window,它将显示项目的详细信息。项目组件会显示所有的项目缩略图,最后项目页面会渲染项目组件。
也许我遗漏了什么。我会感谢你的帮助。
模态组件的代码如下: modal.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Link } from 'gatsby-link'
import './modal.scss'
import MdClose from 'react-icons/lib/md/close'
export class Modal extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
this.initializeEscClosing();
}
initializeEscClosing() {
if (typeof window !== 'undefined') {
window.addEventListener('keydown', (e) => {
if (e.which == 27) {
//this.props.onClose
console.log('It\'s working')
}
});
}
}
render() {
// Render nothing if the "show" prop is false
if (!this.props.show) {
return null;
}
return (
<div className={`modal`}>
<div className={`modal__overlay`}
onClick={this.props.onClose}
onKeyDown = {
this.initializeEscClosing
}
tabIndex = "0"
>
</div>
<div className={`modal__container`}>
<div className={`modal__body`}>
<div className={`top`}>
<button onClick={this.props.onClose}><MdClose /></button>
</div>
<div className={`content`}>
{this.props.children}
</div>
</div>
</div>
</div>
)
}
}
Modal.propTypes = {
onClose: PropTypes.func.isRequired,
show: PropTypes.bool,
children: PropTypes.node
};
export default Modal
我注意到当我按下 ESC
时,该功能被触发了 3 次,因为我的 .json
文件中有 3 个项目。我该如何解决这个问题?
这是项目组件的代码:
project.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {Link} from 'gatsby-link'
import './project.scss'
import {LinkWebsite, ButtonProject} from '../../../components/atoms/button'
import {Modal } from '../modal'
export class Project extends Component {
constructor(props){
super(props)
this.state = {
opened:false
}
this._toggleModal = this._toggleModal.bind(this)
}
_toggleModal(){
this.setState({
opened: !this.state.opened
})
}
render(){
const { title, category, image, logo, children, website} = this.props
return(
<div className="project__container">
<div className="project__preview">
<button onClick={this._toggleModal}>
{logo ? <img src={logo.src} alt={title} /> : null}
<h2>{title} <span className="category">{category}</span></h2>
</button>
</div>
<div className="project__details">
<Modal
onClose={this._toggleModal}
show={this.state.opened}
>
{image ? <img src={image.src} alt={title} /> : null}
<h3>{title} <span className="category">{category}</span></h3>
{children}
{website ? <LinkWebsite link={website}>Voir le site</LinkWebsite> : null}
</Modal>
</div>
</div>
)
}
}
export default Project
Project.propTypes = {
title: PropTypes.string.isRequired,
category: PropTypes.string.isRequired,
image: PropTypes.shape({
src: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
}).isRequired,
logo: PropTypes.shape({
src: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
}).isRequired,
children: PropTypes.element.isRequired,
website: PropTypes.string,
};
Project.defaultProps = {
title: 'Nom du projet',
image: null,
logo: null,
children: 'Texte introductif du projet. Il fourni les éléments clés',
website: null,
};
这是项目页面的代码:
projets.js
import React, { Component } from 'react'
import Link from 'gatsby-link'
import { Project } from '../components/molecules/project'
const projectPage = ({ data }) => {
return(
<div>
<h1>Projets récents</h1>
<div className="projects__container">
{data.allProjectsJson.edges.map(({ node }, i) =>
(<Project
key={i}
title={node.title}
category={node.category}
image={{
src: node.image.childImageSharp.original.src,
alt: node.title,
}}
logo={{
src: node.logo.childImageSharp.original.src,
alt: node.title,
}}
website={node.website}
>
<p dangerouslySetInnerHTML={{ __html: node.description }} />
</Project>),
)}
</div>
</div>
)
}
export default projectPage
export const pageQuery = graphql`
query ProjectsQuery {
allProjectsJson {
edges {
node {
title
category
description
image {
childImageSharp {
original {
src
}
}
}
logo {
childImageSharp {
original {
src
}
}
}
website
}
}
}
}
`;
提前感谢您抽出宝贵时间提供帮助 祝你周五愉快,
亲切的问候, 马拉
你可以尝试使用箭头函数,我手头没有笔记本电脑,对此深表歉意,但你可以尝试这样的方法
// Modal component
...
onClick={()=> {this.props.onClose()}
// Project component
onClose={() => {console.log(‘might be triggered’); this.toggleModal()}}
使用箭头函数让你摆脱构造函数的绑定
我认为 initializeEscClosing() 函数中有些地方不完全正确。 为什么要在其中创建一个侦听器? onKeyDown 本身就是一个监听器。 尝试做这样的事情来触发事件。
<div onKeyDown = {event => this.keyDownHandler(event)}/>
event prop 包含有关键事件的所有信息,因此在处理它的函数中,您可以检查键是否正确并最终关闭模态