React 第五十节 Router 中useNavigationType的使用详细介绍

news2025/6/3 11:27:10

前言

useNavigationType 是 React Router v6 提供的一个钩子,用于确定用户如何导航到当前页面。
它提供了关于导航类型的洞察,有助于优化用户体验和实现特定导航行为。

一、useNavigationType 核心用途

1.1、检测导航方式:

判断用户是通过浏览器动作(前进/后退)还是程序化导航到达当前页面

1.2、优化页面行为:

根据导航类型调整页面效果(如过渡动画

1.3、用户行为分析:

跟踪用户如何与你的应用交互

1.4、恢复滚动位置:

只在需要时恢复滚动位置

二、useNavigationType导航类型值

POP:通过浏览器的前进/后退按钮或历史记录跳转

PUSH:通过程序化导航(如 navigate())添加新条目到历史堆栈

REPLACE:通过程序化导航替换当前历史条目

三、useNavigationType使用说明

3.1、基本用法

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

function MyComponent() {
  const navType = useNavigationType();
  
  return (
    <div>
      <p>导航类型: {navType}</p>
    </div>
  );
}

3.2、完整示例:根据导航类型应用不同动画

import React, { useEffect, useState } from 'react';
import { 
  useNavigationType,
  useLocation,
  Routes,
  Route,
  Link,
  useNavigate
} from 'react-router-dom';

// 主应用组件
export default function App() {
  return (
    <div className="app">
      <header>
        <h1>useNavigationType 示例</h1>
        <nav>
          <Link to="/" className="nav-link">首页</Link>
          <Link to="/about" className="nav-link">关于</Link>
          <Link to="/contact" className="nav-link">联系我们</Link>
        </nav>
      </header>
      
      <main>
        <Routes>
          <Route path="/" element={<HomePage />} />
          <Route path="/about" element={<AboutPage />} />
          <Route path="/contact" element={<ContactPage />} />
        </Routes>
      </main>
      
      <footer>
        <p>尝试使用浏览器前进/后退按钮查看不同效果</p>
      </footer>
    </div>
  );
}

// 页面组件 - 带导航类型检测
function PageTemplate({ title, children }) {
  const navType = useNavigationType();
  const [animation, setAnimation] = useState('');
  
  useEffect(() => {
    // 根据导航类型应用不同动画
    switch(navType) {
      case 'POP':
        setAnimation('slide-in-left');
        break;
      case 'PUSH':
        setAnimation('slide-in-right');
        break;
      case 'REPLACE':
        setAnimation('fade-in');
        break;
      default:
        setAnimation('fade-in');
    }
    
    // 动画结束后重置状态
    const timer = setTimeout(() => setAnimation(''), 500);
    return () => clearTimeout(timer);
  }, [navType]);
  
  return (
    <div className={`page ${animation}`}>
      <div className="navigation-indicator">
        <span className={`indicator ${navType === 'POP' ? 'active' : ''}`}>
          浏览器导航
        </span>
        <span className={`indicator ${navType === 'PUSH' ? 'active' : ''}`}>
          应用内导航
        </span>
        <span className={`indicator ${navType === 'REPLACE' ? 'active' : ''}`}>
          替换导航
        </span>
      </div>
      
      <h2>{title}</h2>
      <div className="page-content">
        {children}
      </div>
    </div>
  );
}

// 具体页面组件
function HomePage() {
  const navigate = useNavigate();
  
  return (
    <PageTemplate title="首页">
      <p>欢迎访问我们的网站!</p>
      <div className="button-group">
        <button 
          onClick={() => navigate('/about')}
          className="btn push-btn"
        >
          普通导航 (PUSH)
        </button>
        
        <button 
          onClick={() => navigate('/contact', { replace: true })}
          className="btn replace-btn"
        >
          替换导航 (REPLACE)
        </button>
      </div>
    </PageTemplate>
  );
}

function AboutPage() {
  return (
    <PageTemplate title="关于我们">
      <p>我们是一家专注于前端技术的公司。</p>
      <p>使用 useNavigationType 可以增强用户体验!</p>
      <ul className="feature-list">
        <li>检测导航来源</li>
        <li>应用不同过渡效果</li>
        <li>优化滚动行为</li>
        <li>增强用户分析</li>
      </ul>
    </PageTemplate>
  );
}

function ContactPage() {
  return (
    <PageTemplate title="联系我们">
      <div className="contact-card">
        <p>邮箱: contact@example.com</p>
        <p>电话: (123) 456-7890</p>
        <p>地址: 前端开发者大街 123</p>
      </div>
    </PageTemplate>
  );
}

四、useNavigationType实际应用场景

4.1、滚动位置恢复

function ProductList() {
  const navType = useNavigationType();
  const listRef = useRef(null);

  // 保存滚动位置
  useEffect(() => {
    const list = listRef.current;
    return () => {
      sessionStorage.setItem('productListScroll', list.scrollTop);
    };
  }, []);

  // 恢复滚动位置 - 仅对浏览器导航生效
  useEffect(() => {
    if (navType === 'POP') {
      const savedScroll = sessionStorage.getItem('productListScroll');
      if (savedScroll) {
        listRef.current.scrollTop = parseInt(savedScroll, 10);
      }
    }
  }, [navType]);

  return (
    <div ref={listRef} className="product-list">
      {/* 产品列表 */}
    </div>
  );
}

4.2、用户行为分析

function AnalyticsTracker() {
  const navType = useNavigationType();
  const location = useLocation();

  useEffect(() => {
    // 发送导航事件到分析平台
    analytics.track('navigation', {
      path: location.pathname,
      navigationType: navType,
      timestamp: Date.now()
    });
  }, [location, navType]);

  return null; // 无UI组件
}

// 在应用中使用
<Routes>
  <Route path="*" element={<AnalyticsTracker />} />
</Routes>

4.3、动态页面过渡

function AnimatedPage({ children }) {
  const navType = useNavigationType();
  const [direction, setDirection] = useState('from-right');
  
  useEffect(() => {
    setDirection(navType === 'POP' ? 'from-left' : 'from-right');
  }, [navType]);

  return (
    <motion.div
      initial={{ x: direction === 'from-right' ? 300 : -300, opacity: 0 }}
      animate={{ x: 0, opacity: 1 }}
      exit={{ x: direction === 'from-right' ? -300 : 300, opacity: 0 }}
      transition={{ duration: 0.3 }}
    >
      {children}
    </motion.div>
  );
}

五、useNavigationType使用注意事项

1.初始加载:应用首次加载时,useNavigationType 返回 POP

2.SSR 兼容性:在服务器端渲染时总是返回 PUSH

3.路由上下文:必须在 <Router> 组件内部使用

4.性能考虑:导航类型变化会导致组件重新渲染

5.结合其他钩子:通常与 useLocation 和 useNavigate 一起使用

六、useNavigationType的替代方案比较

替代方案的优缺点
useNavigationType:可直接提供导航类型信息,但是仅适用于 React Router
history.listen: 是更底层的控制,但是需要手动管理监听器
自定义历史记录: 可以完全控制导航行为,但是实现复杂,需要额外代码

总结

useNavigationType 是 React Router 应用中一个强大的工具,特别适合需要根据导航来源定制行为的场景。通过合理使用,可以显著提升用户体验和应用性能。

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

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

相关文章

【笔记】在 MSYS2(MINGW64)中安装 Python 工具链的记录

#工作记录 &#x1f4cc; 安装背景 操作系统&#xff1a;MSYS2 MINGW64当前时间&#xff1a;2025年6月1日Python 版本&#xff1a;3.12&#xff08;默认通过 pacman 安装&#xff09;目标工具链&#xff1a; pipxnumpypipsetuptoolswheel &#x1f6e0;️ 安装过程与结果记录…

Linux 学习-模拟实现【简易版bash】

1、bash本质 在模拟实现前&#xff0c;先得了解 bash 的本质 bash 也是一个进程&#xff0c;并且是不断运行中的进程 证明&#xff1a;常显示的命令输入提示符就是 bash 不断打印输出的结果 输入指令后&#xff0c;bash 会创建子进程&#xff0c;并进行程序替换 证明&#x…

【中国・珠海】2025 物联网与边缘计算国际研讨会(IoTEC2025)盛大来袭!

2025 物联网与边缘计算国际研讨会&#xff08;IoTEC2025&#xff09;盛大来袭&#xff01; 科技浪潮奔涌向前&#xff0c;物联网与边缘计算已成为驱动各行业变革的核心力量。在此背景下&#xff0c;2025 物联网与边缘计算国际研讨会&#xff08;IoTEC2025&#xff09;即将震撼…

中国高分辨率高质量地面CO数据集(2013-2023)

时间分辨率&#xff1a;日空间分辨率&#xff1a;1km - 10km共享方式&#xff1a;开放获取数据大小&#xff1a;9.83 GB数据时间范围&#xff1a;2013-01-01 — 2023-12-31元数据更新时间&#xff1a;2024-08-19 数据集摘要 ChinaHighCO数据集是中国高分辨率高质量近地表空气污…

GO——内存逃逸分析

一、可能导致逃逸的5中情况 package mainimport "fmt"func main() {f1()f2()f3()f4()f5() }type animal interface {run() }type dog struct{}func (d *dog) run() {fmt.Println("狗在跑") }// 指针、map、切片为返回值的会发生内存逃逸 func f1() (*int,…

MinVerse 3D触觉鼠标的技术原理与创新解析

MinVerse3D触觉鼠标通过三维交互和触觉反馈技术&#xff0c;彻底颠覆了传统二维鼠标的操作方式。用户在操作虚拟物体时&#xff0c;可以真实感知表面质感、重量和阻力。这种技术不仅为数字环境注入了深度与临场感&#xff0c;还在3D设计、游戏开发和工程仿真等领域展现了广泛潜…

乾元通渠道商中标青海省自然灾害应急能力提升工程基层防灾项目

近日&#xff0c;乾元通渠道商中标青海省自然灾害应急能力提升工程基层防灾项目&#xff0c;乾元通作为设备厂家&#xff0c;为项目提供通信指挥类装备&#xff08;多链路聚合设备&#xff09;QYT-X1。 青岛乾元通数码科技有限公司作为国家应急产业企业&#xff0c;深耕于数据调…

openssl-aes-ctr使用openmp加速

openssl-aes-ctr使用openmp加速 openssl-aes-ctropenmp omp for openssl-aes-ctr 本文采用openssl-1.1.1w进行开发验证开发&#xff1b;因为aes-ctr加解密模式中&#xff0c;不依赖与上一个模块的加/解密的内容&#xff0c;所以对于aes-ctr加解密模式是比较适合进行并行加速的…

PHP+MySQL开发语言 在线下单订水送水小程序源码及搭建指南

随着互联网技术的不断发展&#xff0c;在线下单订水送水服务为人们所需要。分享一款 PHP 和 MySQL 搭建一个功能完善的在线订水送水小程序源码及搭建教程。这个系统将包含用户端和管理端两部分&#xff0c;用户可以在线下单、查询订单状态&#xff0c;管理员可以处理订单、管理…

计算机网络第1章(上):网络组成与三种交换方式全解析

目录 一、计算机网络的概念二、计算机网络的组成和功能2.1 计算机网络的组成2.2 计算机网络的功能 三、电路交换、报文交换、分组交换3.1 电路交换&#xff08;Circuit Switching&#xff09;3.2 报文交换&#xff08;Message Switching&#xff09;3.3 分组交换&#xff08;Pa…

Android studio进阶开发(七)---做一个完整的登录系统(前后端连接)

我们已经讲过了okhttp和登录系统的使用&#xff0c;我们今天做一个完整的登录系统&#xff0c;后端用springmybatis去做 数据库内容 -- 创建学生信息表 CREATE TABLE student_info (id SERIAL PRIMARY KEY, -- 添加自增主键name VARCHAR(255) NOT NULL,number INT NOT NULL,…

计算机网络第1章(下):网络性能指标与分层模型全面解析

目录 一、计算机网络的性能指标1.1 性能指标1&#xff1a;速率1.2 性能指标2&#xff1a;带宽1.3 性能指标3&#xff1a;吞吐量1.4 性能指标4&#xff1a;时延1.5 性能指标5&#xff1a;时延带宽积1.6 性能指标6&#xff1a;往返时延1.7 性能指标7&#xff1a;信道利用率 二、计…

恶意软件清理工具,让Mac电脑安全更简单

​你的Mac最近是不是开始表演"电子迷惑行为"&#xff1f;浏览器主页突然变成澳门赌场&#xff0c;风扇转得比直升机螺旋桨还猛......恭喜你&#xff01;可能中奖获得"恶意软件大礼包"&#xff01;别慌&#xff0c;今天就教你用恶意软件清理工具化身数字特工…

HackMyVM-Jabita

信息搜集 主机发现 ┌──(kali㉿kali)-[~] └─$ nmap -sn 192.168.43.0/24 Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-01 05:20 EDT Nmap scan report for 192.168.43.1 Host is up (0.020s latency). MAC Address: C6:45:66:05:91:88 (Unknown) Nmap scan repo…

112 Gbps 及以上串行链路的有效链路均衡

通道均衡已成为当今高速串行链路的关键机制。目前有许多均衡方案&#xff0c;例如发射机加重均衡、接收机CTLE&#xff08;连续时间线性均衡器&#xff09;、FFE&#xff08;前馈均衡器&#xff09;、DFE&#xff08;判决反馈均衡器&#xff09;和FEC&#xff08;前向纠错&…

Python-13(永久存储)

创建并打开文件 open(file,mode)函数 该函数用于打开一个文件并返回对应的文件对象。 file参数指定的是文件路径和文件名&#xff0c;如果没有添加路径&#xff0c;那么默认将文件创建在python的主文件夹里面。mode参数指定的是打开的模式&#xff0c;r表示读取&#xff08;…

记录一次session安装应用recyclerview更新数据的bug

首先抛出异常日志&#xff0c;在 先说结论&#xff1a;因为session安装监听是在点击事件里面&#xff0c;所以会保留旧的对象数据 直接上代码&#xff0c;原有的逻辑是点击时执行session安装&#xff0c;并注册监听回调 private fun installApk(position: Int) {val packageIns…

大数据-274 Spark MLib - 基础介绍 机器学习算法 剪枝 后剪枝 ID3 C4.5 CART

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大模型篇章已经开始&#xff01; 目前已经更新到了第 22 篇&#xff1a;大语言模型 22 - MCP 自动操作 FigmaCursor 自动设计原型 Java篇开…

力扣面试150题--二叉树的锯齿形层序遍历

Day 56 题目描述 思路 锯齿形就是一层是从左向右&#xff0c;一层是从右向左&#xff0c;那么我们可以分析样例&#xff0c;对于第奇数层是从左向右&#xff0c;第偶数层是从右向左&#xff0c;于是可以采取一个计数器&#xff0c;采取链表方式&#xff0c;从左向右就是正常插…

如何在 CentOS / RHEL 上修改 MySQL 默认数据目录 ?

MySQL 是一个广泛使用的开源关系数据库管理系统(RDBMS)&#xff0c;为无数的 web 应用程序和服务提供支持。默认情况下&#xff0c;MySQL 将其数据存储在预定义的目录中&#xff0c;这可能并不总是适合您的需求。您可能希望将数据目录移动到另一个位置以获得更好的性能和安全性…