3

Doing my best to hide this sidebar when a user clicks anywhere outside of the focused area. Currently, when I click outside, the sidebar remains open. If I click in an area within the sidebar that isnt a link, the sidebar closes. Just trying to recreate that effect elsewhere in the app. Have no idea to implement this in React/JS

Thank you for any help you can send my way.

import React, { useState } from 'react';
import * as FaIcons from 'react-icons/fa';
import * as AiIcons from 'react-icons/ai';
import { Link } from 'react-router-dom';
import { NavbarData } from './NavbarData';
import '../styles/Navbar.css';
import { IconContext } from 'react-icons';
import onClickOutsideHOC from "react-onclickoutside"; //<-- Should I be using this?
function Navbar() {
  const [sidebar, setSidebar] = useState(false);

  const showSidebar = () => setSidebar(!sidebar);
  const hideSidebar = () => setSidebar(onClickOutsideHOC()); //<-- Should I be using this?
  return (
    <>
      <IconContext.Provider value={{ color: '#fff' }}>
        <div className='navbar'>
          <Link to='#' className='menu-bars'>
            <FaIcons.FaBars onClick={showSidebar} />
          </Link>
        </div>
        <nav className={sidebar ? 'nav-menu active' : 'nav-menu'}>
          <ul className='nav-menu-items' onClick={showSidebar}>
            <li className='navbar-toggle'>
              <Link to='#' className='menu-bars'>
                <AiIcons.AiOutlineClose />
              </Link>
            </li>
            {NavbarData.map((item, index) => {
              return (
                <li key={index} className={item.cName}>
                  <Link to={item.path}>
                    {item.icon}
                    <span>{item.title}</span>
                  </Link>
                </li>
              );
            })}
          </ul>
        </nav>


//Commented Out My Attempt Below

 {/*      <nav>
          <nav className={sidebar ? 'nav-menu inactive' : 'nav-menu'}>
            <ul className='nav-menu-items' onClick={hideSidebar}>
              <li className='navbar-toggle'>
                <Link to='#' className='menu-bars'>
                  <AiIcons.AiOutlineClose />
                </Link>
              </li>
              {NavbarData.map((item, index) => {
                return (
                    <li key={index} className={item.cName}>
                      <Link to={item.path}>
                        {item.icon}
                        <span>{item.title}</span>
                      </Link>
                    </li>
                );
              })}
            </ul>
          </nav>


        </nav>*/}
      </IconContext.Provider>
    </>
  );
}

export default Navbar;
user7823016
  • 127
  • 2
  • 10
  • Does this answer your question? [How do I detect a click outside an element?](https://stackoverflow.com/questions/152975/how-do-i-detect-a-click-outside-an-element) – lissettdm Mar 14 '21 at 16:03

1 Answers1

6

For this, you can create a custom hook that takes the element you want as a parameter. I created a sandbox for you.

https://codesandbox.io/s/outside-click-hook-uc8bo

We send the ref of the element to the custom hook we created.

const boxRef = useRef(null);
// boxOutsideClick will be true on outside click
const boxOutsideClick = OutsideClick(boxRef); 
<div ref={boxRef} className="box">
    <h1>Click outside of me</h1>
</div>

And our hook will look like this:

export default function OutsideClick(ref) {
const [isClicked, setIsClicked] = useState();
useEffect(() => {
  function handleClickOutside(event) {
    if (ref.current && !ref.current.contains(event.target)) {
      setIsClicked(true);
    } else {
      setIsClicked(false);
    }
  }

  document.addEventListener("mousedown", handleClickOutside);
  return () => {
    document.removeEventListener("mousedown", handleClickOutside);
  };
}, [ref]);
  return isClicked;
}

OnMouseDown, we check if the clicked place is in the selected element and update the isClicked value and return.

Dharman
  • 26,923
  • 21
  • 73
  • 125
İbrahim Akar
  • 260
  • 3
  • 9