You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React下拉菜单添加.active类样式丢失,hover正常求排查

解决React下拉组件点击展开样式异常问题

核心问题分析

  1. 样式作用对象不统一:仅给dropdownContent添加.active类,但hover时的样式是作用在dropdown容器上的,导致点击展开时缺少容器的样式变更,出现菜单收缩错位。
  2. 固定定位高度适配差:dropdownContent用top: 2.5em固定定位,容器样式变化时容易出现位置偏差。
  3. CSS选择器冗余/错误:存在dropdown:hover:hover这类无效选择器,且.dropdown, .dropdown.active合并定义易引发样式覆盖。

修复后的组件代码

import React, { useEffect, useRef, useState } from 'react';
import { faChevronDown } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import './SortResults.css'

const SortResults = () => {
    const [isOpen, setIsOpen] = useState(false);
    const [selectedOption, setSelectedOption] = useState('');
    const sortOptions = ['最新优先', '价格从低到高', '价格从高到低']; // 可自定义选项
    const menuRef = useRef(null);
    
    useEffect(() => {
        const handler = (e) => {
          if (menuRef.current && !menuRef.current.contains(e.target)) {
            setIsOpen(false);
          }      
        };
        document.addEventListener("mousedown", handler);

        return () => {
          document.removeEventListener("mousedown", handler);
        }
    }, []); // 空依赖数组避免重复绑定事件

    const handleClick = (index) => {
        setSelectedOption(sortOptions[index]);
        setIsOpen(false);
    }

    return (   
        <div className={`dropdown ${isOpen ? 'active' : ''}`}>
            <div className="select" onClick={() => setIsOpen(!isOpen)}>
                <p className="selectChoice">
                    {selectedOption || '排序方式'}
                </p>
                <FontAwesomeIcon className="arrow" icon={faChevronDown} />
            </div>
            <div 
                className={`dropdownContent ${isOpen ? 'active' : ''}`}
                ref={menuRef}
            >
                {sortOptions.map((option, index) => (
                    <div 
                        className={index === 0 ? 'sortChoice1' : 'sortChoice'}
                        key={index} 
                        onClick={() => handleClick(index)}
                    >
                        {option}
                    </div>
                ))}
            </div> 
        </div>
    );
};

export default SortResults;

修复后的CSS代码

:root {
    --blue: #165DFF; /* 替换为你的蓝色值 */
    --lightbeige: #FFF9E6; /* 替换为你的浅米色值 */
}

.dropdown {
    z-index: 10; 
    position: relative;
    width: 15em;
    margin-left: 1.5em;
    outline: 2.5px solid black;
    border-radius: 1em;
    background-color: var(--blue);
    cursor: pointer;
    font-family: "Inter", sans-serif;
    font-weight: 600;
    transition: border-radius 0.2s ease;
}

/* 统一hover和active状态的容器样式 */
.dropdown.active,
.dropdown:hover {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    border-bottom: 0;
    outline-bottom: 0;
}

.select {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 2.5em;
    width: 100%;
}

.selectChoice {
    font-family: "Inter", sans-serif;
    font-weight: 600;
}

.arrow {
    position: absolute;
    right: 1em;
    transition: transform 0.2s ease;
}

/* hover和active状态下箭头同步旋转 */
.dropdown:hover .arrow,
.dropdown.active .arrow {
    transform: rotate(180deg);
}

.dropdownContent {
    display: none;
    position: absolute;
    width: 100%;
    top: 100%; /* 紧贴父容器底部,适配任意高度 */
    left: 0;
    overflow: hidden;
    outline: 2.5px solid black;
    border-bottom-left-radius: 1em;
    border-bottom-right-radius: 1em;
    background-color: var(--blue);
    cursor: pointer;
}

/* 统一hover和active状态的菜单显示逻辑 */
.dropdownContent.active,
.dropdown:hover .dropdownContent {
    display: block;
}

.sortChoice1, .sortChoice {
    display: block;
    text-align: center;
    padding-block: 1em;
    width: 100%;
    cursor: pointer;
    border-top: 0;
    transition: background-color 0.15s ease-in-out;
}

.sortChoice {
    border-top: 2.5px solid black;
}

.sortChoice:hover, .sortChoice1:hover {
    background-color: var(--lightbeige);
}

关键修复点

  1. 统一状态作用对象:将.active类添加到最外层dropdown容器,让点击展开和hover的样式逻辑完全对齐。
  2. 动态定位下拉菜单:用top: 100%替代固定的top: 2.5em,确保菜单始终紧贴父容器底部,避免高度变化导致的错位。
  3. 合并重复样式:把hover和active状态的相同样式合并到同一个选择器,减少冗余代码。
  4. 修复React代码问题:补全缺失的状态和导入,给useEffect添加空依赖数组避免重复绑定事件,优化点击逻辑。

内容的提问来源于stack exchange,提问作者Mawin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 16:30:08