我已设置功能,以便当用户点击或触摸通知容器外部时,该框将关闭。但是,我不想直接向DOM添加事件。我宁愿利用React的SyntheticEvent wrapper。有谁知道我如何使用SyntheticEvent,而不是我目前拥有的DOM事件?
到目前为止,这是我的代码:
import React from 'react';
import { PropTypes } from 'prop-types';
import './Notification.scss';
export default class Notification extends React.Component {
constructor(props) {
super(props);
this.setNotificationWrapper = this.setNotificationWrapper.bind(this);
this.handleClickOutside = this.handleClickOutside.bind(this);
this.state = {
visible: false,
hasNotifications: false,
expanded: false,
};
this.toggleNotificationContainer = this.toggleNotificationContainer
.bind(this);
}
componentDidMount() {
document.addEventListener('touchend', this.handleClickOutside);
document.addEventListener('mousedown', this.handleClickOutside);
}
componentWillUnmount() {
document.removeEventListener('touchend', this.handleClickOutside);
document.removeEventListener('mousedown', this.handleClickOutside);
}
setNotificationWrapper(node) {
this.notificationWrapper = node;
}
handleClickOutside(event) {
if (this.notificationWrapper &&
!this.notificationWrapper.contains(event.target)) {
this.toggleNotificationContainer();
event.preventDefault();
}
}
toggleNotificationContainer() {
this.setState({
visible: !this.state.visible,
hasNotifications: this.state.hasNotifications,
expanded: !this.state.expanded,
});
}
createNotificationItems(option, index) {
this.state.hasNotifications = true;
return (
<li
key={index}
value={index}
>
{option.label}
</li>
);
}
render() {
// set up the details to show in the list.
let notificationOptions = null;
let optionCount = 0;
let toggleDivDetails = null;
let buttonStyleName = '';
let buttonText = null;
if (this.props.notificationButtonIcon) {
buttonStyleName = 'notificationButton';
} else {
buttonText = this.props.notificationButtonText;
buttonStyleName = 'notificationButtonWithText';
}
toggleDivDetails = (
<button
onClick={this.toggleNotificationContainer}
styleName={this.state.expanded ? 'expanded' : buttonStyleName}
disabled={this.state.expanded}
>
{buttonText}
</button>
);
if (this.props.options) {
optionCount = this.props.options.length;
notificationOptions = this.props.options.map((option, index) =>
this.createNotificationItems(option, index));
}
if (optionCount === 0) {
this.state.hasNotifications = false;
}
return (
<div styleName="notificationBar">
{toggleDivDetails}
<span
styleName={
this.state.hasNotifications ? 'notificationCount' : 'hidden'
}
>
{optionCount}
</span>
{
this.state.visible &&
<div
styleName="notificationContainer"
ref={this.setNotificationWrapper}
>
<h3 styleName="notificationHeading">Notifications</h3>
<h4 styleName="notificationSubHeading">
{optionCount} notifications
</h4>
<ul styleName="notificationList">
{notificationOptions}
</ul>
</div>
}
</div>
);
}
}
Notification.propTypes = {
options: PropTypes.arrayOf(PropTypes.object),
notificationButtonIcon: PropTypes.bool.isRequired,
notificationButtonText: PropTypes.string.isRequired,
};
Notification.defaultProps = {
options: [],
NotificationButtonIcon: true,
notificationButtonText: 'Toggle Notifications',
};