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

React实现页面区块无路由切换显隐的优化方案咨询

优化方案

核心优化点

  • 合并状态管理:用单个状态记录当前激活的区块,替代多个独立的显示状态,大幅简化状态维护逻辑
  • 抽离配置数据:将按钮的文本、对应区块ID整理成数组,通过循环渲染按钮,避免重复编写JSX
  • 通用处理函数:只写一个点击处理函数,根据传入的区块ID更新激活状态
  • 简化显示判断:渲染区块时,通过当前激活ID匹配决定显示/隐藏

优化后的完整代码

import { useState } from "react";
import { Link } from "react-router-dom";

function Dashboard() {
    // 单个状态记录当前激活区块,默认激活「已报名课程」
    const [activeSection, setActiveSection] = useState('enrolled');

    // 通用切换函数
    const switchSection = (sectionId) => {
        setActiveSection(sectionId);
    };

    // 菜单配置数组,统一管理所有切换项
    const menuItems = [
        { id: 'enrolled', text: '已报名课程' },
        { id: 'favourite', text: '我的收藏课程' },
        { id: 'recommended', text: '推荐课程' },
        { id: 'profile', text: '个人设置' },
        { id: 'password', text: '修改密码' }
    ];

    return (
        <div className="container mt-4">
            <div className="row">
                <aside className="col-md-3">
                    <div className="card">
                        <div className="list-group">
                            <h5 className="card-header">我的控制台</h5>
                            {/* 循环渲染所有切换按钮 */}
                            {menuItems.map(item => (
                                <button
                                    key={item.id}
                                    id={item.id}
                                    onClick={() => switchSection(item.id)}
                                    className={`list-group-item list-group-item-action ${activeSection === item.id ? 'active' : ''}`}
                                >
                                    {item.text}
                                </button>
                            ))}
                            <Link style={{ textDecoration: 'none' }} to="/user-login">
                                <button className="list-group-item list-group-item-action text-danger">退出登录</button>
                            </Link>
                        </div>
                    </div>
                </aside>
                <main className="col-md-9">
                    {/* 区块显示逻辑:匹配激活ID则显示,否则隐藏 */}
                    <div style={{ display: activeSection === 'enrolled' ? 'block' : 'none' }}>
                        <h3>已报名课程内容</h3>
                    </div>
                    <div style={{ display: activeSection === 'favourite' ? 'block' : 'none' }}>
                        <h3>我的收藏课程内容</h3>
                    </div>
                    <div style={{ display: activeSection === 'recommended' ? 'block' : 'none' }}>
                        <h3>推荐课程内容</h3>
                    </div>
                    <div style={{ display: activeSection === 'profile' ? 'block' : 'none' }}>
                        <h3>个人设置内容</h3>
                    </div>
                    <div style={{ display: activeSection === 'password' ? 'block' : 'none' }}>
                        <h3>修改密码内容</h3>
                    </div>
                </main>
            </div>
        </div>
    );
}

export default Dashboard;

复用性扩展

如果后续多个页面需要类似切换逻辑,可以封装成自定义Hook:

// useTabSwitch.js
import { useState } from 'react';

export function useTabSwitch(initialActiveTab) {
    const [activeTab, setActiveTab] = useState(initialActiveTab);
    const switchTab = (tabId) => setActiveTab(tabId);
    return { activeTab, switchTab };
}

在组件中直接调用:

import { useTabSwitch } from './useTabSwitch';

function Dashboard() {
    const { activeTab, switchTab } = useTabSwitch('enrolled');
    // 后续逻辑直接复用activeTab和switchTab即可
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:25:18