如何在创建为样式化组件的自定义 React 模态中检测“onClickOutside”和“onEscapeKeyPress”
How to detect `onClickOutside` and `onEscapeKeyPress` in custom React modal created as a styled component
现在,我已经在这上面花费了大量时间。但是,我无法弄清楚,因为我是使用 styled-components.
的新手
我在 React 中创建了一个 Modal 风格的组件。唯一要做的就是添加 'onClickOutside' 和 'onEscapeKeyPress' 功能。
但是,对于我来说,我无法将事件侦听器添加到 Modal 元素(也无法添加到基础 div
元素)。
Here's a link to codesandbox demo
这是我希望用户使用我的组件的理想方式:
<Modal
show={this.state.isOpen}
onBackgroundClick={this.toggleModal}
onEscapeKeydown={this.toggleModal}
>
<Modal.Wrapper>
<Modal.Header>
<!-- ignore this -->
</Modal.Header>
<Modal.Body>
<!-- ignore this -->
</Modal.Body>
<Modal.Footer>
<!-- ignore this -->
</Modal.Footer>
</Modal.Wrapper>
</Modal>
或
<Modal
show={this.state.isOpen}
closeOnEscape
closeOnClickOutside
>
<Modal.Wrapper>
<Modal.Header>
<!-- ignore this -->
</Modal.Header>
<Modal.Body>
<!-- ignore this -->
</Modal.Body>
<Modal.Footer>
<!-- ignore this -->
</Modal.Footer>
</Modal.Wrapper>
</Modal>
非常感谢任何帮助。
在等待来自 SO 社区的帮助时,我设法自己找到了解决方案。
简而言之,对于那些像我一样对使用样式化组件比较陌生的人来说:样式化组件就是 'styled' 组件。你不能用任何脚本重载它。为了检测 onClickOutside
和 onEscapePress
,我必须创建一个新的包装器 Modal
组件,它在底层使用 StyledModal
组件。检测按键和鼠标按下的代码就在这里。
这里有一些代码片段来解释我的方法:
Modal.js(片段)
componentDidMount() {
this.props.closeOnClickOutside &&
document.addEventListener("mousedown", this.handleClick, false);
this.props.closeOnEscape &&
document.addEventListener("keyup", this.handleKeyPress, false);
}
render() {
return (
<StyledModal
style={{ display: this.props.show ? "block" : "none" }}
ref={this.modal}
>
<Wrapper>{this.props.children}</Wrapper>
</StyledModal>
);
}
样式化Modal.jsx
import styled from "styled-components";
const StyledModal = styled.div`
position: fixed;
padding: 0;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100vh;
background-color: grey;
z-index: 1;
`;
export default StyledModal;
index.js(预期用途)
<Modal
show={this.state.isOpen}
closeOnEscape
onClose={() => this.setState({ isOpen: false })}
>
<Header>I have a nice title</Header>
<Body>But not much to say...</Body>
<Footer>
<button onClick={this.toggleModal}>Cancel</button>
<button onClick={this.toggleModal}>OK</button>
</Footer>
</Modal>
Working Demo
现在,我已经在这上面花费了大量时间。但是,我无法弄清楚,因为我是使用 styled-components.
的新手我在 React 中创建了一个 Modal 风格的组件。唯一要做的就是添加 'onClickOutside' 和 'onEscapeKeyPress' 功能。
但是,对于我来说,我无法将事件侦听器添加到 Modal 元素(也无法添加到基础 div
元素)。
Here's a link to codesandbox demo
这是我希望用户使用我的组件的理想方式:
<Modal
show={this.state.isOpen}
onBackgroundClick={this.toggleModal}
onEscapeKeydown={this.toggleModal}
>
<Modal.Wrapper>
<Modal.Header>
<!-- ignore this -->
</Modal.Header>
<Modal.Body>
<!-- ignore this -->
</Modal.Body>
<Modal.Footer>
<!-- ignore this -->
</Modal.Footer>
</Modal.Wrapper>
</Modal>
或
<Modal
show={this.state.isOpen}
closeOnEscape
closeOnClickOutside
>
<Modal.Wrapper>
<Modal.Header>
<!-- ignore this -->
</Modal.Header>
<Modal.Body>
<!-- ignore this -->
</Modal.Body>
<Modal.Footer>
<!-- ignore this -->
</Modal.Footer>
</Modal.Wrapper>
</Modal>
非常感谢任何帮助。
在等待来自 SO 社区的帮助时,我设法自己找到了解决方案。
简而言之,对于那些像我一样对使用样式化组件比较陌生的人来说:样式化组件就是 'styled' 组件。你不能用任何脚本重载它。为了检测 onClickOutside
和 onEscapePress
,我必须创建一个新的包装器 Modal
组件,它在底层使用 StyledModal
组件。检测按键和鼠标按下的代码就在这里。
这里有一些代码片段来解释我的方法:
Modal.js(片段)
componentDidMount() {
this.props.closeOnClickOutside &&
document.addEventListener("mousedown", this.handleClick, false);
this.props.closeOnEscape &&
document.addEventListener("keyup", this.handleKeyPress, false);
}
render() {
return (
<StyledModal
style={{ display: this.props.show ? "block" : "none" }}
ref={this.modal}
>
<Wrapper>{this.props.children}</Wrapper>
</StyledModal>
);
}
样式化Modal.jsx
import styled from "styled-components";
const StyledModal = styled.div`
position: fixed;
padding: 0;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100vh;
background-color: grey;
z-index: 1;
`;
export default StyledModal;
index.js(预期用途)
<Modal
show={this.state.isOpen}
closeOnEscape
onClose={() => this.setState({ isOpen: false })}
>
<Header>I have a nice title</Header>
<Body>But not much to say...</Body>
<Footer>
<button onClick={this.toggleModal}>Cancel</button>
<button onClick={this.toggleModal}>OK</button>
</Footer>
</Modal>