React实现DropdownItem仅桌面端作为Link跳转的方案问询
Solution
To achieve this responsive dropdown behavior, we’ll implement viewport detection, track dropdown expansion states, and conditionally render interactive elements based on the device type. Here’s a step-by-step breakdown:
Step 1: Add State for Viewport and Dropdown Expansion
First, add state to your Navbar component to track mobile/desktop viewport and which dropdowns are expanded:
import { useState, useEffect } from 'react'; const Navbar = () => { // Adjust 768px to match your project's mobile/desktop breakpoint const [isMobile, setIsMobile] = useState(window.innerWidth < 768); // Track expanded dropdowns using an object (key: dropdown ID, value: expansion state) const [expandedDropdowns, setExpandedDropdowns] = useState({}); // Update mobile state on window resize useEffect(() => { const handleResize = () => { const currentIsMobile = window.innerWidth < 768; setIsMobile(currentIsMobile); // Close all dropdowns when switching from mobile to desktop if (!currentIsMobile) setExpandedDropdowns({}); }; window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); // Toggle dropdown expansion const toggleDropdown = (dropdownId) => { setExpandedDropdowns(prev => ({ ...prev, [dropdownId]: !prev[dropdownId] })); }; // ... rest of your component code };
Step 2: Modify Nav Item Render Logic
Update your existing navItems.map block to conditionally render either a navigation link (desktop) or a dropdown toggle (mobile) for parent items with subitems:
{navItems.map((item, index) => { const dropdownId = `dropdown-${index}`; const isDropdownExpanded = expandedDropdowns[dropdownId] || false; return ( <Item key={index}> {/* Render dropdown trigger or navigation link */} {item.subItems ? ( isMobile ? ( // Mobile: Toggle dropdown on click, no navigation <button onClick={() => toggleDropdown(dropdownId)} className="dropdown-toggle" // Match link styling with this class aria-expanded={isDropdownExpanded} aria-haspopup="true" > {item.label} <ChevronDown className={isDropdownExpanded ? 'chevron-rotated' : ''} /> </button> ) : ( // Desktop: Navigate to the item's path on click <ItemLink to={item.path}> {item.label} <ChevronDown /> </ItemLink> ) ) : ( // Regular items: Always render navigation link <ItemLink to={item.path}> {item.label} </ItemLink> )} {/* Render dropdown menu (expanded on mobile, hover on desktop) */} {item.subItems && ( <MenuDropdown items={item.subItems} isOpen={isMobile ? isDropdownExpanded : undefined} // Omit isOpen for desktop if your MenuDropdown uses hover CSS /> )} </Item> ); })}
Step 3: Add CSS for Mobile Toggle
Style the toggle button to match your existing link styles and add a chevron rotation animation:
/* Match link styles for the toggle button */ .dropdown-toggle { background: none; border: none; color: inherit; font: inherit; cursor: pointer; padding: inherit; text-decoration: none; display: flex; align-items: center; gap: 0.5rem; } /* Rotate chevron when dropdown is expanded */ .chevron-rotated { transform: rotate(180deg); transition: transform 0.2s ease; }
Key Notes
- Breakpoint Adjustment: Change
768pxto match your project’s mobile/desktop threshold (e.g.,992pxfor larger tablets). - Desktop Hover Behavior: If your
MenuDropdownuses CSS hover to show the menu on desktop, omit theisOpenprop for desktop as shown. - Accessibility: The
aria-expandedandaria-haspopupattributes improve screen reader support for mobile users.
内容的提问来源于stack exchange,提问作者Cristian Muscalu
相关产品推荐
相关产品推荐

