React问题:点击时仅为单个组件添加激活状态类并移除其他组件的类
解决方案:统一管理激活状态实现面板互斥激活
问题出在每个Panel组件独立维护自己的激活状态,导致多个面板可以同时处于激活状态,无法实现同一时间仅一个面板激活的需求。我们需要将激活状态提升到父组件统一管理,通过props控制子组件的激活状态。
修改后的父组件 Project.jsx
import "./Project.css"; import Panel from "./Panel.jsx"; import { useState } from "react"; export default function Project() { // 用面板标题作为唯一标识,也可以使用索引值 const [activePanel, setActivePanel] = useState(null); const handlePanelClick = (panelTitle) => { // 点击同一面板时切换激活状态,若不需要取消激活,直接写 setActivePanel(panelTitle) 即可 setActivePanel(activePanel === panelTitle ? null : panelTitle); }; return ( <> <div className="container flex gap-5 w-[100vw] sm:w-[90vw] [&>.active]:flex-[5] [&>.active>h3]:opacity-100 [&>.active>h3]:transition-opacity [&>.active>h3]:duration-300 [&>.active>h3]:ease-in [&>.active>h3]:delay-[400ms] " > <Panel title={"Nature 1"} isActive={activePanel === "Nature 1"} onClick={() => handlePanelClick("Nature 1")} /> <Panel title={"Nature 2"} isActive={activePanel === "Nature 2"} onClick={() => handlePanelClick("Nature 2")} /> <Panel title={"Nature 3"} isActive={activePanel === "Nature 3"} onClick={() => handlePanelClick("Nature 3")} /> <Panel title={"Nature 4"} isActive={activePanel === "Nature 4"} onClick={() => handlePanelClick("Nature 4")} /> <Panel title={"Nature 5"} isActive={activePanel === "Nature 5"} onClick={() => handlePanelClick("Nature 5")} /> </div> </> ); }
修改后的子组件 Panel.jsx
export default function Panel(props) { return ( <div onClick={props.onClick} className={`bg-[url('./assets/img/nature-${props.title.split(' ')[1]}.jpg')] ${props.title.includes("4") || props.title.includes("5") ? "sm-max:hidden" : ""} bg-cover bg-center bg-no-repeat h-[80vh] rounded-[50px] text-[#fff] cursor-pointer flex-[0.5] relative transition-[flex] duration-[700ms] ease-in ${props.isActive ? "active" : ""}`} > <h3 className="text-2xl absolute bottom-5 left-5 m-0 opacity-0"> {props.title} </h3> </div> ); }
关键修改说明
- 状态提升:将激活状态从子组件移到父组件
Project中,通过activePanel变量记录当前激活的面板标识,确保状态统一可控。 - 互斥激活逻辑:父组件的
handlePanelClick函数负责更新激活状态,点击新面板时自动取消之前面板的激活状态,点击同一面板可切换激活状态(可根据需求调整)。 - 样式选择器优化:将原来的
#activeID选择器改为.active类选择器,避免HTML中ID重复的问题,符合规范。 - 动态背景图片:根据面板标题自动拼接背景图片路径,解决原代码中所有面板使用同一张图的问题。
- 响应式修正:修正原代码中响应式隐藏的语法错误,通过标题判断添加隐藏类。
内容的提问来源于stack exchange,提问作者FSzabi
相关产品推荐
相关产品推荐

