在单击模态本身时,关闭外部单击会关闭。在模式之外的任何地方单击时,基本上都不应关闭

时间:2019-06-06 18:59:53

标签: reactjs modal-dialog

此代码之前对我有用,但是我不确定我要在其中使用的其他组件中发生了什么更改。

我尝试使用钩子来打开和关闭模式,只是在单击事件侦听器上很普通,但是两次都在单击页面上的任何位置时都关闭。

componentDidMount() {
    document.addEventListener('click', this.handleOutsideClick);
  }

  componentWillUnmount() {
    document.removeEventListener('click', this.handleOutsideClick);
  }

  handleOutsideClick = (e) => {
    if (this.state.showInfoModal && !this.node.contains(e.target)) this.handleInfoToggle();
    console.log(this.state.showInfoModal, e.target, this.node, 'clicked outside');
  }

  handleInfoToggle = (event) => {
    const { showInfoModal } = this.state;

    if (event) event.preventDefault();
    this.setState({ showInfoModal: !showInfoModal });
  };

renderSomething = (args) => {
 return(
   <span ref={(node) => { this.node = node; }}>
   {something === true && <span className={styles.somethingelse}> 
   <HintIcon onClick={this.handleInfoToggle} /></span>}
    <Modal visible={showInfoModal} onCancel={this.handleInfoToggle}>
     some information to show
    </Modal>
   </span>
  )
}

render() => {
  return (
   {this.renderSomething(args)}
  )
}

不确定这是否足够的信息。但这让我发疯。

我还尝试添加有人建议的dontCloseModal函数:

  dontCloseModal = (e) => {
    e.stopPropagation();
    console.log(e);
    this.setState({
      showInfoModal: true
    });
  }

 <div onClick={this.dontCloseModal}></div>

(((这将在<Modal/>组件周围)))

  const refs = React.createRef(); // Setup to wrap one child
  const handleClick = (event) => {
    const isOutside = () => {
      return !refs.current.contains(event.target);
    };
    if (isOutside) {
      onClick();
    }
  };

  useEffect(() => {
    document.addEventListener('click', handleClick);

    return function() {
      document.removeEventListener('click', handleClick);
    };
  });

  return (element, idx) => React.cloneElement(element, { ref: refs[idx] });
}

export default ClickOutside;

尝试使用类似^^的组件并添加<ClickOutside onClick={this.closeInfoModal()}></ClickOutside> 但是,与此相同的问题也可能会导致在任何位置(包括模态内部)单击

1 个答案:

答案 0 :(得分:0)

玩了一点之后,看来您也应该useRef在这里。 如果用户在模态目标的内部和外部单击,这将允许您控制模态的切换。

有很多复杂的方法可以实现这一目标。但是,由于我们在这里处理钩子,所以最好使用自定义钩子。

介绍useOnClick?:

// Custom hook for controling user clicks inside & outside
function useOnClick(ref, handler) {
    useEffect(() => {
        const listener = event => {
            // Inner Click: Do nothing if clicking ref's element or descendent elements, similar to the solution I gave in my comment stackoverflow.com/a/54633645/4490712 
            if (!ref.current || ref.current.contains(event.target)) {
                return;
            }
            // Outer Click: Do nothing if clicking wrapper ref
            if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
                return;
            }

            handler(event);
        };

        // Here we are subscribing our listener to the document
        document.addEventListener("mousedown", listener);

        return () => {
            // And unsubscribing it when we are no longer showing this component
            document.removeEventListener("mousedown", listener);
        };
    }, []); // Empty array ensures that effect is only run on mount and unmount
}

观看此Demo in CodeSandBox,以便您了解如何使用钩子实现该操作。

欢迎使用StackOverflow!