React 第三十七节 Router 中 useOutlet Hook的使用介绍以及注意事项

news2025/5/10 8:57:37

React Router 中的 useOutlet 是 v6 版本新增的 Hook,用于在父路由组件中访问当前嵌套的子路由元素。它提供了比 <Outlet> 组件更灵活的控制方式,适合需要根据子路由状态进行动态处理的场景。

一、useOutlet的基本用法

import { useOutlet } from 'react-router-dom';

function ParentLayout() {
  // 返回当前匹配的子路由元素(未匹配时返回 null)
  const outlet = useOutlet();

  return (
    <div>
      <h1>Parent Layout</h1>
      <nav>{/* 导航链接 */}</nav>
      
      {/* 等价于直接使用 <Outlet /> */}
      {outlet || <div>Default content when no sub-route matches</div>}
    </div>
  );
}

二、useOutlet的典型使用场景

2.1. 条件渲染布局

function AuthLayout() {
  const outlet = useOutlet();
  
  return (
    <div className="auth-layout">
      {outlet ? (
        // 有子路由时显示带背景的布局
        <div className="auth-background">
          {outlet}
        </div>
      ) : (
        // 无子路由时显示默认内容
        <Navigate to="/login" />
      )}
    </div>
  );
}

2.2. 动态处理子路由

function AnimationLayout() {
  const outlet = useOutlet();
  const [prevOutlet, setPrevOutlet] = useState(outlet);
  
  // 保留旧路由用于退场动画
  if (outlet) setPrevOutlet(outlet);

  return (
    <AnimatePresence mode="wait">
      <motion.div
        key={location.pathname}
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
      >
        {outlet || prevOutlet}
      </motion.div>
    </AnimatePresence>
  );
}

三、useOutlet的路由配置示例

const router = createBrowserRouter([
  {
    path: '/',
    element: <ParentLayout />,
    children: [
      {
        path: 'dashboard',
        element: <Dashboard />,
      },
      {
        path: 'profile',
        element: <UserProfile />,
      }
    ]
  }
]);

四、useOutlet的使用注意事项

4.1、上下文依赖

只能在被 <RouterProvider><BrowserRouter> 包裹的组件中使用,否则会抛出错误。

4.2、路由匹配规则

子路由需要正确配置在父路由的 children 数组中,且路径需要正确嵌套:

// ❌ 错误配置(缺少父路径)
children: [{ path: '/dashboard', ... }]

// ✅ 正确配置
children: [{ path: 'dashboard', ... }] // 实际路径为 /dashboard

4.3、null 值处理

当没有匹配的子路由时返回 null,建议总是处理空状态:

// 推荐写法
{outlet || <FallbackComponent />}

// 危险写法(可能渲染 undefined)
{outlet}

4.4、性能优化

<Outlet> 不同,直接使用 useOutlet 不会自动处理 Suspense,需要自行添加错误边界:

function SafeOutlet() {
  const outlet = useOutlet();
  return <ErrorBoundary>{outlet}</ErrorBoundary>;
}

4.5、路由状态更新

当 URL 变化但父路由保持匹配时,useOutlet 会返回新的 React 元素,可以用 useLocation 监听变化:

const outlet = useOutlet();
const location = useLocation();

useEffect(() => {
  console.log('Sub-route changed:', location.pathname);
}, [location]);

五、useOutlet 与 的对比

在这里插入图片描述

六、useOutlet 使用总结建议:

大多数简单场景直接使用 <Outlet> 更合适

需要以下高级功能时选择 useOutlet:

6.1、动态布局切换
6.2、路由过渡动画
6.3、自定义空状态处理
6.4、基于子路由的复杂条件渲染

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2372175.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AGV通信第3期|AGV集群智能应急响应系统:从故障感知到快速恢复

随着智慧工厂物流系统复杂度的提升&#xff0c;AGV运行过程中的异常处理能力已成为保障生产连续性的关键指标。面对突发障碍、设备故障等意外状况&#xff0c;传统依赖人工干预的响应模式已无法满足现代智能制造对时效性的严苛要求。 一、AGV异常应急体系面临的挑战 响应时效瓶…

军事目标无人机视角坦克检测数据集VOC+YOLO格式4003张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4003 标注数量(xml文件个数)&#xff1a;4003 标注数量(txt文件个数)&#xff1a;4003 …

软件安全(二)优化shellcode

我们在上一节课中所写的shellcode&#xff0c;其中使用到的相关的API是通过写入其内存地址来实现调用。这种方法具有局限性&#xff0c;如切换其他的操作系统API的内存地址就会发生变化&#xff0c;从而无法正常调用。 所谓的shellcode不过是在目标程序中加一个区段使得程序可…

RabbitMQ-运维

文章目录 前言运维-集群介绍多机多节点单机多节点 多机多节点下载配置hosts⽂件配置Erlang Cookie启动节点构建集群查看集群状态 单机多节点安装启动两个节点再启动两个节点验证RabbitMQ启动成功搭建集群把rabbit2, rabbit3添加到集群 宕机演示仲裁队列介绍raft算法协议 raft基…

深度学习基础--目标检测常见算法简介(R-CNN、Fast R-CNN、Faster R-CNN、Mask R-CNN、SSD、YOLO)

博主简介&#xff1a;努力学习的22级本科生一枚 &#x1f31f;​&#xff1b;探索AI算法&#xff0c;C&#xff0c;go语言的世界&#xff1b;在迷茫中寻找光芒​&#x1f338;​ 博客主页&#xff1a;羊小猪~~-CSDN博客 内容简介&#xff1a;常见目标检测算法简介​&#x1f…

LINUX CFS算法解析

文章目录 1. Linux调度器的发展历程2. CFS设计思想3. CFS核心数据结构3.1 调度实体(sched_entity)3.2 CFS运行队列(cfs_rq)3.3 任务结构体中的调度相关字段 4. 优先级与权重4.1 优先级范围4.2 权重映射表 (prio_to_weight[])优先级计算4.3.1. static_prio (静态优先级)4.3.2. n…

软考-软件设计师中级备考 14、刷题 算法

一、考点归纳 1&#xff09;排序 2、查找 3、复杂度 4、经典问题 0 - 1 背包动态规划0 - 1 背包问题具有最优子结构性质和重叠子问题性质。通过动态规划可以利用一个二维数组来记录子问题的解&#xff0c;避免重复计算&#xff0c;从而高效地求解出背包能装下的最大价值。分…

Baklib实战企业内容与中台管理差异解析

企业内容管理中台本质差异 企业内容管理系统&#xff08;CMS&#xff09;与内容中台的核心差异在于战略定位与技术路径的本质性区隔。传统CMS聚焦于内容存储与审批流程的线性管理&#xff0c;而内容中台则构建起全域数据服务中枢&#xff0c;通过API接口实现跨系统内容资产调用…

通用外设驱动模型(四步法)

举例&#xff1a;GPIO配置步骤 1、使能时钟 __HAL_RCC_GPIOx_CLK_ENABLE()2、设置工作模式 HAL_GPIO_Init()3、设置输出状态&#xff08;可选&#xff09; HAL_GPIO_WritePin() HAL_GPIO_TogglePin()4、读取输入状态&#xff08;可选&#xff09; HAL_GPIO_ReadPin()模块…

IoT无线组网模块,万物互联的底层通信基石

随着物联网&#xff08;IoT&#xff09;技术在“快车道”上持续飞驰&#xff0c;一场“交互革命”正在人们的日常出行与工作学习等生活场景中加速爆发。从智能家居到智慧城市&#xff0c;从智慧交通到工业自动化&#xff0c;物联网&#xff08;IoT&#xff09;技术凭借着万物互…

learning ray之ray强化学习/超参调优和数据处理

之前我们掌握了Ray Core的基本编程&#xff0c;我们已经学会了如何使用Ray API。现在&#xff0c;让我们将这些知识应用到一个更实际的场景中——构建一个强化学习项目&#xff0c;并且利用Ray来加速它。 我们的目标是&#xff0c;通过Ray的任务和Actor&#xff0c;将一个简单…

【Linux】深入拆解Ext文件系统:从磁盘物理结构到Linux文件管理

目录 1、理解硬件 &#xff08;1&#xff09;磁盘 &#xff08;2&#xff09;磁盘的物理结构 &#xff08;3&#xff09;磁盘的存储结构 &#xff08;4&#xff09;磁盘的逻辑结构 &#xff08;5&#xff09;CHS && LBA地址 2、引入文件系统 &#xff08;1&…

基于 Ubuntu 24.04 部署 WebDAV

无域名&#xff0c;HTTP 1. 简介 WebDAV&#xff08;Web Distributed Authoring and Versioning&#xff09;是一种基于 HTTP 的协议&#xff0c;允许用户通过网络直接编辑和管理服务器上的文件。本教程介绍如何在 Ubuntu 24.04 上使用 Apache2 搭建 WebDAV 服务&#xff0c;无…

tauri-plugin-store 这个插件将数据存在本地电脑哪个位置

tauri-plugin-store 插件用于在 Tauri 应用中以键值对形式持久化存储数据。它将数据存储在用户本地电脑的一个 JSON 文件中&#xff0c;具体路径取决于操作系统&#xff0c;并且通常位于操作系统的应用数据目录中。 默认存储位置 以默认配置为例&#xff08;使用 default sto…

一场陟遐自迩的 SwiftUI + CoreData 性能优化之旅(下)

概述 自从 SwiftUI 诞生那天起&#xff0c;我们秃头码农们就仿佛打开了一个全新的撸码世界&#xff0c;再辅以 CoreData 框架的鼎力相助&#xff0c;打造一款持久存储支持的 App 就像探囊取物般的 Easy。 话虽如此&#xff0c;不过 CoreData 虽好&#xff0c;稍不留神也可能会…

数字人驱动/动画方向最新顶会期刊论文收集整理 | AAAI 2025

会议官方论文列表&#xff1a;https://ojs.aaai.org/index.php/AAAI/issue/view/624 以下论文部分会开源代码&#xff0c;若开源&#xff0c;会在论文原文的摘要下方给出链接。 语音驱动头部动画/其他 EchoMimic: Lifelike Audio-Driven Portrait Animations through Editabl…

数据结构 集合类与复杂度

文章目录 &#x1f4d5;1. 集合类&#x1f4d5;2. 时间复杂度✏️2.1 时间复杂度✏️2.2 大O渐进表示法✏️2.3 常见的时间复杂度量级✏️2.4 常见时间复杂度计算举例 &#x1f4d5;3. 空间复杂度 &#x1f4d5;1. 集合类 Java 集合框架&#xff08;Java Collection Framework…

Python学习笔记--Django的安装和简单使用(一)

一.简介 Django 是一个用于构建 Web 应用程序的高级 Python Web 框架。Django 提供了一套强大的工具和约定&#xff0c;使得开发者能够快速构建功能齐全且易于维护的网站。Django 遵守 BSD 版权&#xff0c;初次发布于 2005 年 7 月, 并于 2008 年 9 月发布了第一个正式版本 1…

SecureCRT网络穿透/代理

场景 公司的办公VPN软件只有Windows系统版本&#xff0c;没有Macos系统版本&#xff0c;而日常开发过程中需要先登录VPN后&#xff0c;然后才能登录应用服务器。 目的&#xff1a;Macos系统在使用SecureCRT时&#xff0c;登录服务器&#xff0c;需要走Parallels Desktop进行网络…

视频添加字幕脚本分享

脚本简介 这是一个给视频添加字幕的脚本&#xff0c;可以方便的在指定的位置给视频添加不同大小、字体、颜色的文本字幕&#xff0c;添加方式可以直接修改脚本中的文本信息&#xff0c;或者可以提前编辑好.srt字幕文件。脚本执行环境&#xff1a;windowsmingwffmpeg。本方法仅…