Sandy
Sandy

Reputation: 224

How to manage the click event to show/hide certain element in React?

This weekend, I tried to build a Search component myself using React. Before doing that, I needed to build an input select component but I decided to build it from scratch using Div as I need to apply my own style to it. When I click on a Div, I am gonna show the list of some items. And if I click outside of that list items, it can be hidden. Also, when I click the Div again(when a list item is open), I want to hide that list item too. But it doesn't work. I am using this code.

import { useState, useRef, useEffect } from 'react';

function useVisible(initialIsVisible = false) {
  const [isVisible, setIsVisible] = useState(initialIsVisible);
  const ref = useRef(null);

  const handleClickOutside = (event) => {
    if (ref.current && !ref.current.contains(event.target)) {
      setIsVisible(false);
    }
  };

  useEffect(() => {
    document.addEventListener('click', handleClickOutside, true);
    return () => {
      document.removeEventListener('click', handleClickOutside, true);
    };
  }, []);

  return { ref, isVisible, setIsVisible };
}

export default useVisible;

Hey, Nemanja Lazarevic

Here it is:

import React from 'react';
import useVisible from './useVisible';

// In the component
const { ref, isVisible, setIsVisible } = useVisible();

// In return
<div onClick={setIsVisible}>
  Select items
</div>
{isVisible && (
  <div ref={ref}>
    // list items here
  </div>
)}

Upvotes: 3

Views: 1398

Answers (2)

adel
adel

Reputation: 3507

hey you code work perfectly but maybe you implementation is wrong and i suggest adding handleClickOutside inside useEffect:

   import React, { useRef, useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const [isVisible, setIsVisible] = useState(false);
  const ref = useRef(null);

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (ref.current && !ref.current.contains(event.target)) {
        setIsVisible(false);
      }
    };
    document.addEventListener("click", handleClickOutside, false);
    return () => {
      document.removeEventListener("click", handleClickOutside, false);
    };
  }, []);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={(e) => {
      e.stopPropagation();
      setIsVisible(!isVisible);
    }}>open modal</button>
      <div
        ref={ref}
        className="modal"
        style={{ display: isVisible ? "block" : "none" }}
      />
    </div>
  );
}

full working example : codeSanbox

Upvotes: 0

thaovd1712
thaovd1712

Reputation: 318

I use modal in ant design to show or hide the element, you can see this example

{isVisible && (
      <Modal
        visible={isVisible}
        onOk={() => handleVerifyOkButton()}
        onCancel={() => setIsVerify(false)}
      >
       List Item
      </Modal>
    )}

Upvotes: 1

Related Questions