Мне нужно чтобы при открытии модального окна контент страницы не скроллило и при клике вне зоны контента окно закрывалось)
/// Modal.jsx
import React, { Component } from 'react'
import stylesOfModal from './Modal.module.scss'
import Portal from '../Portal'
import { ImCross } from 'react-icons/im'
class Modal extends Component {
render() {
return (
<>
{this.props.isOpen &&
<Portal>
<div className={stylesOfModal.modalOverlay}>
<div className={stylesOfModal.modalContent} onClick={e => e.stopPropagation()}>
<div className={stylesOfModal.modalHeader}>
<div>{this.props.header}</div>
<ImCross
style={{cursor: "pointer"}}
onClick={this.props.closeBtn}
/>
</div>
<div className={stylesOfModal.modalBody}>
{this.props.children}
</div>
<div className={stylesOfModal.modalFooter}>
<button
style={{marginRight: '15px', cursor: 'pointer'}}
onClick={this.props.onCancel} invert='true'>
Cancel
</button>
<button
style={{cursor: 'pointer'}}
onClick={this.props.onSubmit}>
Submit
</button>
</div>
</div>
</div>
</Portal>
}
</>
)
}
}
export default Modal;
/// App.jsx
import React, { Component } from 'react';
import Button from './components/Button/Button'
import Modal from './components/Modal/Modal';
class App extends Component {
state = {
isOpen: false,
text: ''
}
toggleBtn = (newText) => {
this.setState({isOpen: !this.state.isOpen, textForModal: newText})
}
clickedOnCross = () => {
this.setState({ isOpen: false, textForModal: '' })
}
handleSubmit = () => {
console.log('Submited!');
this.setState({ isOpen: false, textForModal: '' });
}
handleCancel = () => {
console.log('Canceled!');
this.setState({ isOpen: false, textForModal: '' });
}
render() {
return (
<div>
<Button
backgroundColor='rgb(0, 0, 255)'
text='Open first modal'
onClick={() => this.toggleBtn("First button is opened with random text")}
/>
<Button
backgroundColor='rgb(255, 234, 0)'
text='Open second modal'
onClick={() => this.toggleBtn("And this is my custom text")}
/>
<Modal
closeBtn={this.props.clickedOnCross}
isOpen={this.state.isOpen}
onCancel={this.handleCancel}
onSubmit={this.handleSubmit}
header='Modal made with React'>
{this.state.textForModal}
</Modal>
</div>
)
}
}
export default App
/// Button.jsx
import React, { Component } from 'react'
import styles from './Button.module.scss'
class Button extends Component {
render() {
return (
<div className={styles.linkContainer}>
<a
style{{backgroundColor:`${this.props.backgroundColor}`}}
className={styles.link}
onClick={this.props.onClick}>
{this.props.text}
</a>
</div>
)
}
}
export default Button;
/// Portal.jsx
import { Component } from 'react';
import ReactDOM from 'react-dom';
class Portal extends Component {
el = document.createElement('div');
componentDidMount() {
document.body.appendChild(this.el);
}
componentWillUnmount() {
document.body.removeChild(this.el);
}
render() {
const { children } = this.props;
return ReactDOM.createPortal(children, this.el);
}
}
export default Portal;
Ответы (1 шт):
Автор решения: isma.teem
→ Ссылка
В App.js
toggleBtn = (newText) => {
document.body.style.overflow = "hidden" // Выключаешь скролл при открытии
this.setState({ isOpen: !this.state.isOpen, textForModal: newText })
}
handleCancel = () => {
document.body.style.overflow = "scroll" // Включаешь скролл при закрытии
console.log("Canceled!")
this.setState({ isOpen: false, textForModal: "" })
}
И на корневой div в Modal.jsx добавляешь onClick
<div className={stylesOfModal.modalOverlay} onClick={this.props.onCancel}>