简体   繁体   中英

Closing popup on clicking outside component

Before wrote this post, I saw this post , but i'm not able to link all of the code to mine.

This is my toggle component:

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

and this is the inside of 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>
  );
}

and this is the wrapper of LogoutCard inside the props 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>;
}

Problem

The problem is that I'm able to print the alert, but i'm not able to close the popup because I'm not able to pass the show value, that's in the only allowed to close and open the little popup.

Question

How can I close the popup ?

You need to pass a say a name, onClick function to handle the logic needed to execute to close the popup as needed. Also simplifying the logic to an toggle action that just negates the current state would be enough to manage the show / hide behaviour of the popup.

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>
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM