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

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>
  );
}

关键修改说明

  1. 状态提升:将激活状态从子组件移到父组件Project中,通过activePanel变量记录当前激活的面板标识,确保状态统一可控。
  2. 互斥激活逻辑:父组件的handlePanelClick函数负责更新激活状态,点击新面板时自动取消之前面板的激活状态,点击同一面板可切换激活状态(可根据需求调整)。
  3. 样式选择器优化:将原来的#active ID选择器改为.active类选择器,避免HTML中ID重复的问题,符合规范。
  4. 动态背景图片:根据面板标题自动拼接背景图片路径,解决原代码中所有面板使用同一张图的问题。
  5. 响应式修正:修正原代码中响应式隐藏的语法错误,通过标题判断添加隐藏类。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 19:20:13