首页 > 解决方案 > 在选择一个项目或在其外部单击时关闭列表项下拉列表

问题描述

我在我的 react js 项目中创建了一个下拉列表,其中包含列表项(下拉项在此处由 ul 和 li 标签显示)。

我面临的问题是,在选择任何项目时,状态值会发生变化,但下拉菜单不会关闭,当我点击它之外的任何地方时它不会关闭。请帮帮我,这是同一个 repo 的工作代码和框 url

在这里检查

我也在分享下面的代码。

应用程序.js

import React, { Component, useState } from "react";
import Dropdown from "./dropdown";
import "./dropdown.css";

const App = () => {
  const [value, setValue] = useState("");
  const [showDropdown, setShowDropdown] = useState(false);

  const selectedValue = (value) => {
    console.log(value);
    setValue(value);
  };
  const onSelectItem = () => {
    console.log("12");
    setShowDropdown(false);
  };

  return (
    <section className="shadow-border" id="FlightsForm">
      <div className="top-sec d-flex">
        <div className="left-side">
          <span
            className="custm-dropdown"
            onClick={() => setShowDropdown(true)}
          >
            <span style={{ backgroundColor: "grey", color: "white" }}>
              {value.tripType}
            </span>
            <span className="dropdown-icon"> </span>
            <Dropdown
              selectedValue={selectedValue}
              onSelectItem={onSelectItem}
              showDropdown={showDropdown}
            />
          </span>
        </div>
      </div>
    </section>
  );
};

export default App;

Dropdown.js

import React from "react";
import { useState, useEffect } from "react";

const TripTypeDropdown = (props) => {
  const [values, setValues] = useState([
    { tripType: "One Way", value: 1 },
    { tripType: "Return", value: 2 },
    { tripType: "Multi- City", value: 3 },
  ]);
  const [selectedItem, setSelectedItem] = useState({
    tripType: "One Way",
    value: 1,
  });
  useEffect(() => {
    props.selectedValue(selectedItem);
    console.log(selectedItem);
  }, [selectedItem]);

  const selectItemFromList = (index) => {
    const itemSelected = values[index];
    setSelectedItem(itemSelected);
    props.onSelectItem();
  };
  const getActiveClassName = (item) => {
    if (selectedItem) {
      if (item.tripType == selectedItem.tripType) return "active";
      else return "";
    }
  } ;
  return (
    <React.Fragment>
      <div
        className={`dropdown-modal sm-modal ripple trip-type-dropdown`}
        style={{ display: `${props.showDropdown ? "block" : "none"}` }}
      >
        <ul>
          {console.log(values)}
          {values.map((item, index) => (
            <li
              className={getActiveClassName(item)}
              onClick={() => selectItemFromList(index)}
              key={index}
               style={{backgroundColor:'yellow',border:"1px solid black",listStyle:"none"}}
            >
              {item.tripType}
            </li>
          ))}
        </ul>
      </div>
    </React.Fragment>
  );
};

export default TripTypeDropdown;

标签: javascriptcssreactjs

解决方案


您需要停止将单击事件从下拉组件冒泡到它的父 span 元素。单击时,您需要传递 event 参数和stopPropagation事件对象的调用函数

这是冷凝箱

Dropdown.js

const selectItemFromList = (e,index) => {
    e.stopPropagation();

...

<li
     className={getActiveClassName(item)}
     onClick={(e) => selectItemFromList(e,index)}
     key={index}

还添加了外部点击的代码。

const ref = useRef();

...

useEffect(() => {
    document.addEventListener("click", handleDropdownClick);
  }, [ref]);

const handleDropdownClick = (e) => {
    e.stopPropagation();
    if (ref.current && ref.current.contains(e.target)) {
      setShowDropdown(true);
    } else {
      setShowDropdown(false);
    }
  };

...

<span
     ref={ref}
     className="custm-dropdown"
     onClick={handleDropdownClick}
 >

推荐阅读