【问题标题】:this.wrapperRef.current.contains(element) returns false although element is a grand childthis.wrapperRef.current.contains(element) 返回 false 尽管 element 是一个孙子
【发布时间】:2021-07-14 20:47:43
【问题描述】:

包装器EditModal 组件带有onClickOutside 事件。此模式的子组件是Material-UI Select。单击MenuItem 会触发onClickOutside,从而关闭模式而不选择新值。

问题的根源是this.wrapperRef.current.contains(element) 返回false,即使MenuItemEditModal 的孙子。

为什么会这样?如何避免这种行为?

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;

【问题讨论】:

    标签: javascript reactjs material-ui react-ref


    【解决方案1】:

    一位同事找到了答案。 Material-UI 生成的弹出菜单不会作为Select 的子元素放置在 DOM 中。

    要修复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}
              >
    
      [...]
    

    【讨论】:

      猜你喜欢
      • 2021-12-31
      • 2015-08-17
      • 2016-03-01
      • 1970-01-01
      • 2023-01-18
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多