React中FAQ筛选栏选中li元素样式持久化实现方案
Got it, let's fix this! The issue here is that the :active and :focus pseudo-classes only apply temporarily during the interaction—once you release the mouse or click elsewhere, they disappear. To keep the active style persistent, we need to track the selected filter with React state and apply a dedicated CSS class to the active item.
Step-by-Step Solution
1. Add State to Track the Active Filter
First, update your Filters component to manage which category is currently selected using React state. This will let us persist the active state between clicks.
2. Update the Click Handler
Create a custom click handler that updates the active state and still triggers your parent component's filter logic.
3. Dynamically Apply the Active Class
In the render method, conditionally add an active class to the selected <li> element based on the current state.
4. Adjust CSS for Persistent Active Styles
Modify your CSS to style the active class with the black color and underline you want.
Updated Code
React Component
import React from 'react'; export default class Filters extends React.Component { constructor(props) { super(props); // Initialize state with the default active filter ("all") this.state = { activeFilter: 'all' }; // Bind the handler to ensure correct `this` context this.handleFilterClick = this.handleFilterClick.bind(this); } handleFilterClick(e) { const selectedFilter = e.target.getAttribute('data-item'); // Update state with the newly selected filter this.setState({ activeFilter: selectedFilter }); // Call the parent component's filter function with the selected value this.props.filter(selectedFilter); } render() { const { activeFilter } = this.state; return ( <div className="portfolio-list"> <ul className="nav list-unstyled" id="portfolio-flters"> <li className={`faqnav ${activeFilter === 'all' ? 'filter-active' : ''}`} data-item="all" onClick={this.handleFilterClick} >All</li> <li className={`faqnav ${activeFilter === 'general' ? 'filter-active' : ''}`} data-item="general" onClick={this.handleFilterClick} >General</li> <li className={`faqnav ${activeFilter === 'stats' ? 'filter-active' : ''}`} data-item="stats" onClick={this.handleFilterClick} >Stats</li> <li className={`faqnav ${activeFilter === 'account' ? 'filter-active' : ''}`} data-item="account" onClick={this.handleFilterClick} >Account</li> <li className={`faqnav ${activeFilter === 'social' ? 'filter-active' : ''}`} data-item="social" onClick={this.handleFilterClick} >Social Media</li> </ul> </div> ); } }
Updated CSS
#portfolio .portfolio-list .nav li { margin: 0 40px 0 0; float: left; color: #C42B32; line-height: 16px; cursor: pointer; font-size: 20px; font-weight: 600 !important; font-family: 'Assistant', sans-serif !important; letter-spacing: 0.02em; transition: all 0.5s ease-in-out 0s; text-transform: uppercase; } #portfolio .portfolio-list .nav li:hover { color: #000000; transition: all 0.5s ease-in-out 0s; } /* Persistent style for actively selected filter */ #portfolio .portfolio-list .nav li.filter-active { color: #000000 !important; text-decoration: underline; transition: all 0.5s ease-in-out 0s; } /* Optional: Keep focus styles for accessibility */ #portfolio .portfolio-list .nav li:focus, #portfolio .portfolio-list .nav li:focus-within { outline: 2px solid #C42B32; /* Helps keyboard users see selected items */ }
How This Works
- The
activeFilterstate keeps track of which category is selected, so the style persists until another category is clicked. - The
handleFilterClickfunction updates the state and passes the selected filter value to your parent component's existing filter logic. - The
filter-activeclass is dynamically added to the selected<li>, ensuring the black color and underline stay visible until the user selects a different category. - We kept focus styles with an outline for accessibility, so keyboard users can still navigate and see which item is active.
内容的提问来源于stack exchange,提问作者Ollie

