如何使用useState Hook为Div添加激活状态(默认首个激活)
Tab切换激活状态异常修复方案
问题描述
我拥有4个Div组件,期望点击时仅当前Div显示绿色底部边框,且首个Div默认处于激活状态。但编写的代码会将所有Div都设置为激活状态,原代码如下:
import React, {useState} from "react"; const MenuItems = ({ icon, title, color, tabNum, setTabIndex }) => { const [selected, setSelected] = useState(false); return ( <div style={selected? {borderBottom:"2px solid green"} : null} onClick={() => setSelected(selected)}> <p onClick={() => setTabIndex(tabNum)} style={{ color: color }} className="p-1 shadow-md flex flex-col items-center justify-center cursor-pointer" > {icon} <span className="text-xs text-black">{title}</span> </p> </div> ); }; export default MenuItems;
问题原因
每个MenuItems组件都独立维护了自己的selected状态,且点击事件里setSelected(selected)是无效操作(等于把状态设为当前值,没有变化)。这种分散的状态管理无法实现“仅当前Div激活”的需求,因为每个组件的状态互不关联。
解决思路与修改代码
1. 状态提升到父组件
把激活状态的管理移到父组件,让父组件控制当前选中的tab索引,这样所有子组件的激活状态都由父组件统一调度。
2. 修改子组件MenuItems
去掉子组件内部的selected状态,改为接收父组件传入的activeTab(当前激活的tab索引)和setActiveTab(更新激活状态的方法),通过比较tabNum和activeTab来判断自身是否激活:
import React from "react"; const MenuItems = ({ icon, title, color, tabNum, activeTab, setActiveTab }) => { return ( <div style={tabNum === activeTab ? {borderBottom:"2px solid green"} : null} onClick={() => setActiveTab(tabNum)} > <p style={{ color: color }} className="p-1 shadow-md flex flex-col items-center justify-center cursor-pointer" > {icon} <span className="text-xs text-black">{title}</span> </p> </div> ); }; export default MenuItems;
3. 父组件示例
父组件中初始化activeTab为0(实现首个Div默认激活),并渲染4个MenuItems组件,传入对应的参数:
import React, { useState } from "react"; import MenuItems from "./MenuItems"; const TabContainer = () => { // 默认激活第一个tab(索引0) const [activeTab, setActiveTab] = useState(0); // 模拟4个tab的数据 const tabs = [ { icon: "🔍", title: "搜索", color: "#333" }, { icon: "📁", title: "文件", color: "#333" }, { icon: "⚙️", title: "设置", color: "#333" }, { icon: "👤", title: "个人", color: "#333" } ]; return ( <div className="flex"> {tabs.map((tab, index) => ( <MenuItems key={index} icon={tab.icon} title={tab.title} color={tab.color} tabNum={index} activeTab={activeTab} setActiveTab={setActiveTab} /> ))} </div> ); }; export default TabContainer;
关键说明
- 父组件通过
activeTab控制全局激活状态,子组件仅负责根据传入的状态渲染样式 - 点击子组件时,调用父组件的
setActiveTab更新激活索引,确保只有当前点击的Div处于激活状态 - 初始化
activeTab为0,实现首个Div默认显示绿色底部边框
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

