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

ReactJS无路由组件切换:按侧边栏选择渲染对应页面

React无路由切换组件修复方案

问题分析

你的代码存在三个核心问题导致组件无法正确切换:

  1. Dashboard组件用useEffect控制渲染内容错误:直接在useEffect中给变量赋值,React渲染机制会导致变量在组件重渲染时被重置,且useEffect是副作用钩子,不适合用来控制UI渲染。
  2. 未处理Shop组件的渲染逻辑:Dashboard只判断了executables分支,点击Shop按钮后没有对应组件渲染。
  3. Sidebar中Settings按钮的onClick写法错误:直接调用setSection("settings")会导致组件挂载时立即执行,而非点击时触发。

修复代码

1. 修改Components/Dashboard.tsx

去掉useEffect,改用组件映射的方式直接返回对应内容:

import styled from "styled-components"
import Executable from "./Executable"
import Shop from "./Shop" // 确保导入Shop组件
import Navbar from "./Navbar"

type EntryProps = {
  section: string
}

const Dashboard = ({ section }: EntryProps) => {
  // 用对象映射组件,简洁易维护
  const sectionMap = {
    executables: (
      <div className="grid">
        <div className="row">
          <Executable />
        </div>
      </div>
    ),
    shop: <Shop />
  }

  return (
    <Section>
      <Navbar />
      {/* 渲染对应组件,无匹配时返回null */}
      {sectionMap[section as keyof typeof sectionMap] || null}
    </Section>
  )
}

// 补充组件导出(原代码遗漏)
export default Dashboard

2. 修改Components/Sidebar.tsx

修复Settings按钮的onClick逻辑,移除Shop按钮中不必要的e.preventDefault():

import styled from "styled-components"
import { FaBars } from "react-icons/fa"
import { BsFileEarmarkBinary } from "react-icons/bs"
import { BiLogOut } from "react-icons/bi"
import { AiOutlineShoppingCart } from "react-icons/ai"
import { IoMdSettings } from "react-icons/io"

import { useState } from "react"

// 给setSection定义精确类型,替代模糊的Function
type SidebarProps = {
  section: string
  setSection: (name: string) => void
}

const Sidebar = ({ section, setSection }: SidebarProps) => {
  const [disabled, setDisabled] = useState(true)
  const handleDisabled = () => setDisabled(!disabled)

  return (
    <Aside id="aside">
      <div
        className={disabled ? "brand center" : "brand"}
        onClick={handleDisabled}
      >
        <FaBars />
      </div>
      <ul className="links">
        <li>
          <BsFileEarmarkBinary />
          <span
            className={disabled ? "disabled" : ""}
            onClick={() => setSection("executables")}
          >
            Executables
          </span>
        </li>
        <li>
          <AiOutlineShoppingCart />
          <span
            className={disabled ? "disabled" : ""}
            onClick={() => setSection("shop")}
          >
            Shop
          </span>
        </li>
        <li>
          <IoMdSettings />
          <span
            className={disabled ? "disabled" : ""}
            onClick={() => setSection("settings")} {/* 修复为箭头函数 */}
          >
            Settings
          </span>
        </li>
      </ul>
      <div className="logout">
        <BiLogOut />
      </div>
    </Aside>
  )
}

export default Sidebar

3. 补充Pages/DashboardPage.tsx的样式与导出(原代码遗漏)

import styled from "styled-components"
import Sidebar from "../components/Sidebar"
import Rightsidebar from "../components/Rightsidebar"
import Dashboard from "../components/Dashboard"
import { useState } from "react"

// 补充容器样式(根据你的需求自定义)
const Div = styled.div`
  display: flex;
  width: 100vw;
  height: 100vh;
`

const DashboardPage = () => {
  const [page, setPage] = useState("executables")

  const setSection = (name: string) => {
    setPage(name)
  }
  
  return (
    <Div>
      <Sidebar section={page} setSection={setSection} />
      <Dashboard section={page} />
      <Rightsidebar />
    </Div>
  )
}

export default DashboardPage

额外优化建议

  • 可以给section设置默认 fallback 组件,避免未匹配时页面空白。
  • 后续新增页面只需在sectionMap中添加键值对即可,无需修改渲染逻辑,扩展性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 08:10:20