javascript - 单击外部组件时关闭弹出窗口

标签 javascript reactjs react-hooks

在写这篇文章之前,我看到了this post ,但我无法将所有代码链接到我的代码。

这是我的切换组件:

<ToggleContent
          toggle={show => (
            <div>
              <button type="button" onClick={show} className={styles.acronym}>
                {acronym}
              </button>
            </div>
          )
          }
          content={show => (
            <LogoutCard onClick={show} acronym={acronym} name={name} />
          )}
        />

这是ToggleContent的内部

function ToggleContent({ toggle, content }) {
  const [isShown, setIsShown] = useState(false);
  const hide = () => setIsShown(false);
  const show = () => setIsShown(!isShown);

  return (
    <Fragment>
      {toggle(show)}
      {isShown && content(hide)}
    </Fragment>
  );
}

这是 Prop 中 LogoutCard 的包装 content

import React, { useRef, useEffect } from "react";

/**
 * Hook that alerts clicks outside of the passed ref
 */
function useOutsideAlerter(ref) {
  /**
   * Alert if clicked on outside of element
   */
  function handleClickOutside(event) {
    if (ref.current && !ref.current.contains(event.target)) {
      alert("You clicked outside of me!");
    }
  }

  useEffect(() => {
    // Bind the event listener
    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      // Unbind the event listener on clean up
      document.removeEventListener("mousedown", handleClickOutside);
    };
  });
}

/**
 * Component that alerts if you click outside of it
 */
export default function OutsideAlerter(props) {
  const wrapperRef = useRef(null);
  useOutsideAlerter(wrapperRef);

  return <div ref={wrapperRef}>{props.children}</div>;
}

问题

问题是我能够打印警报,但无法关闭弹出窗口,因为我无法传递 show 值,这是唯一允许的关闭并打开小弹出窗口。

问题

如何关闭弹出窗口?

最佳答案

您需要传递一个名称,onClick 函数来处理根据需要执行关闭弹出窗口所需的逻辑。此外,将逻辑简化为仅否定当前状态的 toggle 操作就足以管理弹出窗口的显示/隐藏行为。

import React, { useRef, useEffect } from "react";

/**
 * Hook that alerts clicks outside of the passed ref
 */
function useOutsideAlerter(ref, onClick) {
  /**
   * Alert if clicked on outside of element
   */
  function handleClickOutside(event) {
    if (ref.current && !ref.current.contains(event.target)) {
      alert("You clicked outside of me!");
      onClick();
    }
  }

  useEffect(() => {
    // Bind the event listener
    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      // Unbind the event listener on clean up
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [handleClickOutside]);
}

/**
 * Component that alerts if you click outside of it
 */
export default function OutsideAlerter(props) {
  const wrapperRef = useRef(null);

  return <div ref={wrapperRef}>{props.children}</div>;
}

function ToggleContent({ toggle, content }) {
  const [isShown, setIsShown] = useState(false);

  const toggle = () => setIsShown(!isShown);

  const onClick = () => {
    toggle()
  }
  useOutsideAlerter(wrapperRef, onClick);

  return (
    <Fragment>
      {toggle(show)}
      {isShown && content()}
    </Fragment>
  );
}

关于javascript - 单击外部组件时关闭弹出窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56804790/

相关文章:

javascript - AngularJS ng-repeat 在填充表时创建三个空行并且 ng-repeat 不重复

javascript - 如何在用 TypeScript 编写的 Angular Controller 上访问范围值(在测试中)?

javascript - 获取不同类型的两个对象的相同部分

javascript - 如何停止在渲染中一次又一次调用函数

javascript - 与在 useEffect 中分配转发的 ref 相比,useImperativeHandle 有什么好处?

javascript - Internet Explorer 中的 jQuery UI 对话框和 maxHeight

javascript - ReactJS 没有给出 DOM 输出

javascript - 我可以使用来自 CDN 的 React-Select Async (AsyncSelect) 吗? (我收到 Uncaught ReferenceError : exports is not defined)

reactjs - 将箭头函数传递给使用钩子(Hook)的组件会导致 useEffect 再次触发

reactjs - React with Hooks 中的两种数据绑定(bind)方式