1

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 ?

1
  • It would be good if you can put this in a jsFiddle or codeSandbox or something. Commented Jun 28, 2019 at 10:12

1 Answer 1

1

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> ); } 
Sign up to request clarification or add additional context in comments.

2 Comments

just a question that can sound stupid, but consider it's my second month as web dev: i can reach the function ` useOutsideAlerter(wrapperRef, onClick); ` By import only the component OutsideAlerter ( the wrapper of logoutCard ) ?
No. Also you should import it where it should be executed. And in your case, the place where it is appropriate is the ToggleContent component. OutsideAlerter is the function that you render inside ToggleContent through the prop content.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.