Запустите функцию, чтобы закрыть модальное окно в ReactJS - PullRequest
0 голосов
/ 27 апреля 2018

Я создаю свой раздел портфолио в ReactJS с Gatsby, и у меня есть некоторые проблемы с обработкой KeyDown. Мой код позволяет мне определять, когда я нажимаю на клавишу ESC, но я не могу вызвать функцию закрытия, как я делал для оверлея (событие onClick). У меня есть три разных файла:

  • modal.js - Модальный компонент
  • project.js - Компонент проекта
  • projets.js - страница проекта

Я создаю модальное окно, которое будет отображать детали проекта. Компонент проекта отобразит все эскизы проекта, и, наконец, на странице проекта отобразится Компонент проекта.

Может быть, мне чего-то не хватает. Я буду признателен за вашу помощь.

Вот код для модального компонента: 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&eacute;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
      }
    }
  }
}
`;

Заранее спасибо, что нашли время помочь Желаю вам отличной пятницы,

С уважением, Марал

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Я думаю, что в функции initializeEscClosing () что-то не совсем правильно. Почему вы создаете слушателя внутри него? onKeyDown - это слушатель сам по себе. Попробуйте сделать что-то подобное, чтобы вызвать событие.

<div onKeyDown = {event =>  this.keyDownHandler(event)}/>

event prop имеет всю информацию о ключевом событии, поэтому в функции, которая его обрабатывает, вы можете проверить, является ли ключ правильным, и в конечном итоге закрыть модальное

0 голосов
/ 27 апреля 2018

Вы можете попробовать использовать функции стрелок, у меня нет ноутбука, извинитесь за это, но вы можете попробовать что-то вроде этого

// Modal component 
...
onClick={()=> {this.props.onClose()}

// Project component
onClose={() => {console.log(‘might be triggered’); this.toggleModal()}}

Использование функций со стрелками избавляет вас от привязки функций из конструкторов

источник

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...