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

如何用react-router-dom实现/programs路由自动重定向到默认子路由?

问题描述

我使用react-router-dom搭建路由,其中/programs路由会渲染侧边导航栏和<Outlet/>。当访问/programs时,<Outlet/>区域为空,希望用户输入/programs URL时自动跳转到/programs/myprograms。此前使用<Navigate/>(原redirect())会先渲染整个页面,想找更优的实现方式。

现有路由配置

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <Error />,
    children: [
      { path: "/", element: <Home /> },
      { path: "progress", element: <Progress /> },
      { path: "logworkout", element: <LogWorkout /> },
      {
        path: "programs",
        element: <Programs />,
        children: [
          { path: "discover", element: <DiscoverPrograms /> },
          { path: "myprograms", element: <MyPrograms /> },
        ],
      },
      { path: "product", element: <Product /> },
      { path: "contact", element: <Contact /> },
    ],
  },
]);

Programs组件代码

import SideBar from "../../components/Programs/SideBar";
import { Outlet } from "react-router-dom";

const Programs = () => {
  return (
    <div className="grid overflow-hidden" style={{gridTemplateColumns: "auto 1fr"}}>
      <SideBar />
      <div className="overflow-auto">
        <Outlet />
      </div>
    </div>
  );
};

export default Programs;
最优实现方案

在react-router-dom v6中,最推荐的方式是通过添加index路由处理父路由根路径的跳转,这种方式不会先渲染父组件内容,直接完成路由重定向,彻底避免页面闪烁问题。

方法1:添加index路由(优先选择)

修改路由配置,给programs的子路由新增一个index路由,使用<Navigate replace to="myprograms" />作为元素:

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <Error />,
    children: [
      { path: "/", element: <Home /> },
      { path: "progress", element: <Progress /> },
      { path: "logworkout", element: <LogWorkout /> },
      {
        path: "programs",
        element: <Programs />,
        children: [
          // 新增index路由,处理/programs根路径跳转
          { index: true, element: <Navigate replace to="myprograms" /> },
          { path: "discover", element: <DiscoverPrograms /> },
          { path: "myprograms", element: <MyPrograms /> },
        ],
      },
      { path: "product", element: <Product /> },
      { path: "contact", element: <Contact /> },
    ],
  },
]);

这里的replace属性会替换浏览器历史记录中的当前条目,用户点击返回时不会回到空的/programs页面,体验更流畅。

方法2:组件内处理(备选方案)

如果不想修改路由配置,也可以在Programs组件内通过钩子判断路径后跳转,但这种方式仍会先渲染侧边栏再跳转,不如方法1高效:

import SideBar from "../../components/Programs/SideBar";
import { Outlet, useLocation, useNavigate, useEffect } from "react-router-dom";

const Programs = () => {
  const location = useLocation();
  const navigate = useNavigate();

  useEffect(() => {
    if (location.pathname === "/programs") {
      navigate("myprograms", { replace: true });
    }
  }, [location.pathname, navigate]);

  return (
    <div className="grid overflow-hidden" style={{gridTemplateColumns: "auto 1fr"}}>
      <SideBar />
      <div className="overflow-auto">
        <Outlet />
      </div>
    </div>
  );
};

export default Programs;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:15:55