React使用Outlet实现路由跳转时局部刷新页面

Outlet是react-router-dom插件的一个组件,首先需要安装react-router-dom插件:
cnpm i react-router-dom --save

官方文档

应该在父路由元素中用来渲染其子路由元素。这允许在渲染子路由时显示嵌套的 UI。如果父路由完全匹配,则将渲染子索引路由;如果没有索引路由,则不渲染任何内容。

function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>

      {/* This element will render either <DashboardMessages> when the URL is
          "/messages", <DashboardTasks> at "/tasks", or null if it is "/"
      */}
      <Outlet />
    </div>
  );
}

function App() {
  return (
    <Routes>
      <Route path="/" element={<Dashboard />}>
        <Route
          path="messages"
          element={<DashboardMessages />}
          />
        <Route path="tasks" element={<DashboardTasks />} />
      </Route>
    </Routes>
  );
}

实现

效果演示

首页初始化状态:
在这里插入图片描述
进入/home且改变页面其他区域的状态:
在这里插入图片描述
点击去购物车的按钮,进入购物车页面,页面内容局部刷新,页面其他区域的状态不变:
在这里插入图片描述

代码

router.tsx:

import { createBrowserRouter } from 'react-router-dom'
import { OutletDemo } from '../grammar'
import { Cart, Home } from '../pages'

const router = createBrowserRouter([
  {
    path: '/',
    element: <OutletDemo />,
    children: [
      {
        path: 'home',
        element: <Home />,
      },
      {
        path: 'cart',
        element: <Cart />,
      },
    ],
  },
])
export default router

App.tsx:

import './App.css'
import { RouterProvider } from 'react-router-dom'
import router from './routes/router'

function App() {
  return (
    <>
      <RouterProvider router={router} />
    </>
  )
}

export default App

OutletDemo.tsx:
第82行插入Outlet组件

import { Outlet } from 'react-router-dom'
import React from 'react'
import {
  LaptopOutlined,
  NotificationOutlined,
  UserOutlined,
} from '@ant-design/icons'
import type { MenuProps } from 'antd'
import { Breadcrumb, Layout, Menu, theme } from 'antd'

const { Header, Content, Sider } = Layout

const items1: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
  key,
  label: `nav ${key}`,
}))

const items2: MenuProps['items'] = [
  UserOutlined,
  LaptopOutlined,
  NotificationOutlined,
].map((icon, index) => {
  const key = String(index + 1)

  return {
    key: `sub${key}`,
    icon: React.createElement(icon),
    label: `subnav ${key}`,

    children: new Array(4).fill(null).map((_, j) => {
      const subKey = index * 4 + j + 1
      return {
        key: subKey,
        label: `option${subKey}`,
      }
    }),
  }
})

export const OutletDemo: React.FC = () => {
  const {
    token: { colorBgContainer, borderRadiusLG },
  } = theme.useToken()

  return (
    <Layout>
      <Header style={{ display: 'flex', alignItems: 'center' }}>
        <div className="demo-logo" />
        <Menu
          theme="dark"
          mode="horizontal"
          defaultSelectedKeys={['2']}
          items={items1}
          style={{ flex: 1, minWidth: 0 }}
        />
      </Header>
      <Layout>
        <Sider width={200} style={{ background: colorBgContainer }}>
          <Menu
            mode="inline"
            defaultSelectedKeys={['1']}
            defaultOpenKeys={['sub1']}
            style={{ height: '100%', borderRight: 0 }}
            items={items2}
          />
        </Sider>
        <Layout style={{ padding: '0 24px 24px' }}>
          <Breadcrumb style={{ margin: '16px 0' }}>
            <Breadcrumb.Item>Home</Breadcrumb.Item>
            <Breadcrumb.Item>List</Breadcrumb.Item>
            <Breadcrumb.Item>App</Breadcrumb.Item>
          </Breadcrumb>
          <Content
            style={{
              padding: 24,
              margin: 0,
              minHeight: 280,
              background: colorBgContainer,
              borderRadius: borderRadiusLG,
            }}
          >
            <Outlet />
          </Content>
        </Layout>
      </Layout>
    </Layout>
  )
}

Home.tsx:

import { useState } from 'react'
import { useNavigate, Link, Navigate } from 'react-router-dom'

export const Home = () => {
  const navigate = useNavigate()
  const [condition, setCondition] = useState(true)

  return (
    // <button onClick={() => navigate('/cart')}>
    //   Home
    // </button>
    <Link to="/cart">去购物车</Link>
    // condition ? (
    //   <Navigate to="/cart" replace={false}>
    //     去购物车
    //   </Navigate>
    // ) : (
    //   <div>不去</div>
    // )
  )
}

Cart.tsx:

export const Cart = () => {
  return <div>Cart</div>
}

相关推荐

  1. vue3页面如何滚动到顶部

    2024-05-13 13:12:05       42 阅读
  2. vue3页面如何滚动到顶部

    2024-05-13 13:12:05       41 阅读
  3. 鸿蒙跨包页面-HSP页面

    2024-05-13 13:12:05       52 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-13 13:12:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-13 13:12:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-13 13:12:05       82 阅读
  4. Python语言-面向对象

    2024-05-13 13:12:05       91 阅读

热门阅读

  1. 如何在Python中自定义异常?

    2024-05-13 13:12:05       32 阅读
  2. JVM调优:JVM常用调优命令和参数

    2024-05-13 13:12:05       31 阅读
  3. LeetCode hot100-33-Y

    2024-05-13 13:12:05       29 阅读
  4. jdk安装使用(Linux)

    2024-05-13 13:12:05       30 阅读
  5. NIUKE SQL:进阶挑战 (上)

    2024-05-13 13:12:05       23 阅读
  6. 开发中遇到SQL IN传入参数的个数超过2100的bug

    2024-05-13 13:12:05       30 阅读
  7. Leetcode 429:N叉树的层次遍历

    2024-05-13 13:12:05       31 阅读
  8. fastjson的漏洞分析和解决方案

    2024-05-13 13:12:05       36 阅读