首页 > 解决方案 > How to close dropdown on outside click NEXT.JS

问题描述

I am developing an ecommerce store having search input and the result is showing as dropdown. Now searching and the search result showing is working. Now I want to close the dropdown on outside click of dropdown. Please check the below code,

const dispatch = useDispatch();
const [toggleSearch, setToggleSearch] = useState(false);
const {trending, searched} = useSelector(state => state.search);

function trendingSearch(e) {
    setToggleSearch(true);
    
    dispatch(fetchtrending());
}

function startSearch(e) {
    let q = e.target.value;

    dispatch(fetchsearch(q));

    setToggleSearch(true);
}

<div className="col-12 col-md-6 col-lg-7 mt-3 mb-3 mt-md-0 mb-md-0">
    <div className="search-box">
        <div className="search-inner">
            <input type="text" name="q" placeholder="Search for products, brands and much more" onFocus={(e) => trendingSearch(e)} onChange={(e) => startSearch(e)} />
            <button><FontAwesomeIcon icon={faSearch}/></button>
        </div>
        <div className={toggleSearch ? "search-result" : "search-result d-none"}>
            <ul>
                {searched !== null && searched.data.length > 0 &&
                    searched.data.map((search, index) => (
                        <li key={index}><Link href={"/product/"+search.search_slug+"?pid="+search.search_pid}><a>{search.search_name}</a></Link></li>
                    ))
                }
            </ul>
       </div>
    </div>
</div>

I have tried using onBlur for input. But the problem is I can't click links inside search result dropdown.

How to achieve closing dropdown only on click outside the the dropdown.

标签: javascriptreactjsnext.js

解决方案


You can add a click event listener (when the dropdown is opened) to either a backdrop element or the window itself to detect a click outside of the dropdown. Below is an implementation that I check if the click dropdown element contains the event.target.

const { useState, useEffect, useRef } = React;

function App() {
  const [showDropdown, setShowDropdown] = useState(false);
  // create a React ref for the dropdown element
  const dropdown = useRef(null);

  useEffect(() => {
    // only add the event listener when the dropdown is opened
    if (!showDropdown) return;
    function handleClick(event) {
      if (dropdown.current && !dropdown.current.contains(event.target)) {
        setShowDropdown(false);
      }
    }
    window.addEventListener("click", handleClick);
    // clean up
    return () => window.removeEventListener("click", handleClick);
  }, [showDropdown]);

  return (
    <div className="App">
      <button onClick={() => setShowDropdown(b => !b)}>Toggle Dropdown</button>
      {showDropdown && (
        <div
          ref={dropdown}
          style={{ width: 100, height: 100, backgroundColor: "#bada55" }}
        />
      )}
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("App"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="App"></div>


推荐阅读