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

Vite+React TS中动态模板页面的可扩展实现问询

解决方案

一、实现带动态ID的可扩展路由

1. 基础动态路由配置

直接在现有路由规则中添加动态参数:id,React Router会自动匹配该位置的任意字符串作为ID参数。改造后的路由代码如下:

import { Router, Routes, Route } from 'react-router-dom';
// 注意:React组件首字母需大写,这里修正组件命名规范
import Home from './components/Home';
import AboutUs from './components/AboutUs';
import Template1 from './components/Template1';
import Template2 from './components/Template2';
import Template3 from './components/Template3';
import Template4 from './components/Template4';
import Template5 from './components/Template5';

function App() {
  return (
    <Router>
      <div className="App">
        <SidePanel/>
        
        <Routes>          
          <Route path="/" element={<Home />}/>
          <Route path="/about" element={<AboutUs />}/>
          {/* 带动态ID的模板路由 */}
          <Route path="/template1/:id" element={<Template1 />}/>
          <Route path="/template2/:id" element={<Template2 />}/>
          <Route path="/template3/:id" element={<Template3 />}/>
          <Route path="/template4/:id" element={<Template4 />}/>
          <Route path="/template5/:id" element={<Template5 />}/>
        </Routes>
        <SecondaryPanel/>
      </div>
    </Router>
  )
}

然后在模板组件内,通过useParams钩子获取路由中的ID参数:

// Template1.tsx
import { useParams } from 'react-router-dom';

export default function Template1() {
  // 用TypeScript约束参数类型
  const { id } = useParams<{ id: string }>();
  // 后续可通过id请求对应数据或渲染内容
  return <div>当前内容ID:{id}</div>;
}

2. 高可扩展性路由管理(适配大量模板场景)

如果后续需要新增更多模板,可把路由配置抽成数组,通过循环生成Route组件,避免重复编写路由代码:

// 定义路由配置数组,新增模板直接追加即可
const templateRoutes = [
  { path: '/template1', element: <Template1 /> },
  { path: '/template2', element: <Template2 /> },
  { path: '/template3', element: <Template3 /> },
  { path: '/template4', element: <Template4 /> },
  { path: '/template5', element: <Template5 /> },
];

function App() {
  return (
    <Router>
      <div className="App">
        <SidePanel/>
        
        <Routes>          
          <Route path="/" element={<Home />}/>
          <Route path="/about" element={<AboutUs />}/>
          {/* 循环生成带动态ID的路由 */}
          {templateRoutes.map((route) => (
            <Route 
              key={route.path}
              path={`${route.path}/:id`}
              element={route.element}
            />
          ))}
        </Routes>
        <SecondaryPanel/>
      </div>
    </Router>
  )
}

二、SidePanel的ID传递方案

不需要将SidePanel的ID选择功能迁移到App.tsx,推荐两种实用方案:

1. 路由导航传递ID(最推荐)

在SidePanel组件中使用useNavigate钩子,用户选择ID后直接跳转到对应模板的路由:

// SidePanel.tsx
import { useNavigate } from 'react-router-dom';

export default function SidePanel() {
  const navigate = useNavigate();

  // 处理ID选择逻辑,参数为选中的模板类型和ID
  const handleIdSelect = (templateType: string, id: string) => {
    // 跳转到目标路由,比如/template1/5Exo4a
    navigate(`/${templateType}/${id}`);
  };

  return (
    <div className="SidePanel">
      {/* 示例UI:选择模板和ID的按钮 */}
      <button onClick={() => handleIdSelect('template1', '5Exo4a')}>
        打开模板1(ID:5Exo4a)
      </button>
      <button onClick={() => handleIdSelect('template2', '5Exo4a')}>
        打开模板2(ID:5Exo4a)
      </button>
    </div>
  );
}

这种方式的优势是ID会同步到浏览器地址栏,支持页面刷新、链接分享,符合单页应用的路由设计规范。

2. Context共享ID状态(适配跨组件同步场景)

如果除了模板组件,还有SecondaryPanel等其他组件需要获取当前选中的ID,可以通过React Context共享状态:

// IdContext.tsx
import { createContext, useContext, useState, ReactNode } from 'react';

// 定义Context类型
type IdContextType = {
  currentId: string | null;
  setCurrentId: (id: string | null) => void;
  currentTemplate: string | null;
  setCurrentTemplate: (template: string | null) => void;
};

const IdContext = createContext<IdContextType | undefined>(undefined);

// 提供Context的Provider组件
export function IdProvider({ children }: { children: ReactNode }) {
  const [currentId, setCurrentId] = useState<string | null>(null);
  const [currentTemplate, setCurrentTemplate] = useState<string | null>(null);

  return (
    <IdContext.Provider value={{ currentId, setCurrentId, currentTemplate, setCurrentTemplate }}>
      {children}
    </IdContext.Provider>
  );
}

// 自定义Hook,简化Context调用
export function useIdContext() {
  const context = useContext(IdContext);
  if (!context) {
    throw new Error('useIdContext必须在IdProvider内部使用');
  }
  return context;
}

在App.tsx外层包裹IdProvider:

function App() {
  return (
    <IdProvider>
      <Router>
        {/* 原有路由内容 */}
      </Router>
    </IdProvider>
  );
}

SidePanel中更新状态并导航:

// SidePanel.tsx
import { useIdContext } from './IdContext';
import { useNavigate } from 'react-router-dom';

export default function SidePanel() {
  const { setCurrentId, setCurrentTemplate } = useIdContext();
  const navigate = useNavigate();

  const handleIdSelect = (templateType: string, id: string) => {
    setCurrentId(id);
    setCurrentTemplate(templateType);
    navigate(`/${templateType}/${id}`);
  };

  // ...UI部分
}

其他组件(如Template1、SecondaryPanel)可通过useIdContext获取当前ID和模板类型:

// SecondaryPanel.tsx
import { useIdContext } from './IdContext';

export default function SecondaryPanel() {
  const { currentId, currentTemplate } = useIdContext();
  return (
    <div className="SecondaryPanel">
      当前模板:{currentTemplate},当前ID:{currentId}
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 02:55:16