如何解决this.wrapperRef.current.contains(element) 返回 false 虽然 element 是一个孙子
包装器 EditModal
组件带有 onClickOutside
事件。此模式的子组件是 Material-UI Select
。单击 MenuItem
会触发 onClickOutside
,从而关闭模态而不选择新值。
问题的根源在于 this.wrapperRef.current.contains(element)
返回 false
,即使 MenuItem
是 EditModal
的孙子。
为什么会这样?如何避免这种行为?
https://codesandbox.io/s/select-inside-edit-modal-l69zj?file=/src/edit-modal.js (代码改编自this blog)
import React,{ createRef } from "react";
import Select from "@material-ui/core/Select";
import MenuItem from "@material-ui/core/MenuItem";
class EditModal extends React.Component {
constructor(props) {
super(props);
this.wrapperRef = createRef();
this.state = { value: props.initialValue };
}
componentDidMount() {
document.body.addEventListener("mousedown",this.onClickOutside);
}
componentWillUnmount() {
document.removeEventListener("mousedown",this.onClickOutside);
}
onClickOutside = (e) => {
const { onClose } = this.props;
const element = e.target;
if (this.wrapperRef.current && !this.wrapperRef.current.contains(element)) {
console.log(this.wrapperRef.current.contains(element));
e.preventDefault();
e.stopPropagation();
onClose();
}
};
onChange = (e) => {
const { onClose } = this.props;
this.setState({ value: e.target.value });
this.props.onChange(e.target.value);
onClose();
};
render() {
const value = this.state.value;
return (
<div className="modal--overlay">
<div className="modal" ref={this.wrapperRef}>
<h1>Select a new value</h1>
<Select
id="demo-customized-select"
value={value}
color="primary"
onChange={this.onChange}
>
<MenuItem value={"A"}>A</MenuItem>
<MenuItem value={"B"}>B</MenuItem>
<MenuItem value={"C"}>C</MenuItem>
</Select>
</div>
</div>
);
}
}
export default EditModal;
解决方法
一位同事找到了答案。 Material-UI 生成的弹出菜单未放置为 DOM 中 Select
的子项。
要修复 onClickOutside
,应使用 Select
属性 MenuProps 添加引用此菜单的附加条件。
https://codesandbox.io/s/select-inside-edit-modal-forked-wrz7t?file=/src/edit-modal.js:1382-1448
[...]
this.wrapperRef = createRef();
this.inputRef = createRef();
[...]
if (
this.wrapperRef.current &&
!this.wrapperRef.current.contains(element) &&
(this.inputRef.current === null ||
(this.inputRef.current && !this.inputRef.current.contains(element)))
) {
[...]
<Select
MenuProps={{
ref: this.inputRef
}}
id="demo-customized-select"
value={value}
color="primary"
onChange={this.onChange}
>
[...]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。