React 第六十一节 Router 中 createMemoryRouter的使用详解及案例注意事项

发布于:2025-06-14 ⋅ 阅读:(20) ⋅ 点赞:(0)

前言

createMemoryRouterReact Router 提供的一种特殊路由器,它将路由状态存储在内存中而不是浏览器的 URL 地址栏中
这种路由方式特别适用于测试非浏览器环境(如 React Native)以及需要完全控制路由历史的场景。

一、createMemoryRouter 的主要用途

  1. 测试环境:在单元测试和集成测试中模拟路由行为
  2. 非浏览器环境:在 React Native、ElectronNode.js 服务器端渲染中使用
  3. 组件沙盒:在 Storybook 或类似工具中独立运行路由组件
  4. 路由历史控制:需要编程式控制完整路由历史的场景
  5. 无 URL 环境:在不需要地址栏显示路由变化的应用中使用

二、createMemoryRouter 与 createBrowserRouter 的关键区别

在这里插入图片描述

三、createMemoryRouter 完整代码示例

3.1、 基础路由配置

// src/MemoryRouterDemo.jsx
import React from 'react';
import {
   
  createMemoryRouter,
  RouterProvider,
  Link,
  Outlet,
  useLocation
} from 'react-router-dom';

// 页面组件
function Home() {
   
  return (
    <div className="page">
      <h1>首页</h1>
      <p>欢迎使用内存路由示例</p>
      <div className="page-nav">
        <Link to="/about" className="nav-link">关于我们</Link>
        <Link to="/products" className="nav-link">产品列表</Link>
      </div>
    </div>
  );
}

function About() {
   
  return (
    <div className="page">
      <h1>关于我们</h1>
      <p>我们是一家专注于前端技术的公司</p>
      <Link to="/" className="back-link">返回首页</Link>
    </div>
  );
}

// 布局组件
function RootLayout() {
   
  const location = useLocation();
  
  return (
    <div className="app">
      <header className="app-header">
        <h1 className="logo">内存路由示例</h1>
        <div className="url-display">
          当前路由: <code>{
   location.pathname || '/'}</code>
        </div>
        <nav className="main-nav">
          <Link to="/" className="nav-item">首页</Link>
          <Link to="/about" className="nav-item">关于</Link>
          <Link to="/products" className="nav-item">产品</Link>
        </nav>
      </header>
      
      <main className="app-content">
        <Outlet /> {
   /* 子路由渲染位置 */}
      </main>
      
      <footer className="app-footer">
        <p>当前使用: <code>createMemoryRouter</code> | 路由历史: {
   location.key}</p>
      </footer>
    </div>
  );
}

// 创建内存路由配置
const router = createMemoryRouter([
  {
   
    path: "/",
    element: <RootLayout />,
    children: [
      {
   
        index: true,
        element: <Home />
      },
      {
   
        path: "about",
        element: <About />
      },
      {
   
        path: "products",
        element: <ProductsList />
      }
    ]
  }
], {
   
  initialEntries: ["/"], // 初始路由
  initialIndex: 0 // 初始路由索引
});

// 产品列表组件
function ProductsList() {
   
  const products = [
    {
    id: 1, name: 'React 教程', price: 99 },
    {
    id: 2, name: 'Node.js 实战', price: 129 },
    {
    id: 3, name: 'TypeScript 指南', price: 89 }
  ];
  
  return (
    <div className="page">
      <h1>产品列表</h1>
      <div className="products-grid">
        {
   products.map(product => (
          <div key={
   product.id} className="product-card">
            <h3>{
   product.name}</h3>
            <p>价格: ¥{
   product.price}</p>
          </div>
        ))}
      </div>
      <Link to="/" className="back-link">返回首页</Link>
    </div>
  );
}

// 导出使用内存路由的应用
export default function MemoryRouterDemo() {
   
  return <RouterProvider router={
   router} />;
}

3.2、 在 Storybook 中使用 createMemoryRouter

// src/stories/UserProfile.stories.jsx
import React from 'react';
import {
    createMemoryRouter