React中常用的hook函数(四)——useRef、useNavigate、useLocation和useSearchParams

一、useRef

1. 基础概念:

useRef 返回一个可变的 ref 对象,这个对象的 .current 属性可以用来存储一个值,该值在组件的生命周期内是持久化的,并且它不会导致组件重新渲染。

语法:
const myRef = useRef(initialValue);
  • initialValue:这是 useRef 的初始值,通常是 null 或者某个值。
  • myRef:这是返回的一个对象,具有 .current 属性,存储着你希望持久化的数据。

2. 用法 1:获取和操作 DOM 元素

比如,你可能需要在某个操作发生时聚焦一个输入框,或者读取一个 DOM 元素的尺寸信息等。

示例:访问 DOM 元素

import React, { useRef, useEffect } from 'react';const FocusInput = () => {const inputRef = useRef(null);useEffect(() => {// 组件加载完成后,自动聚焦到输入框inputRef.current.focus();}, []);return (<div><input ref={inputRef} type="text" /></div>);
};

声明一个ref对象,通过input的ref属性将ref对象绑定,此时inputRef的current属性会指向该输入框的 DOM 元素

3. 用法 2:保持对数据的引用(不会触发重新渲染)

除了访问 DOM 元素,useRef 还可以用来存储其他可变的数据(例如计时器 ID、上一个值等),并且它不会引起组件重新渲染。

示例:持久化某个值

import React, { useState, useRef, useEffect } from 'react';const TimerComponent = () => {const [seconds, setSeconds] = useState(0);const timerRef = useRef(null);useEffect(() => {timerRef.current = setInterval(() => {setSeconds(prev => prev + 1);}, 1000);// 清理计时器return () => clearInterval(timerRef.current);}, []);return (<div><h1>{seconds} seconds</h1></div>);
};
  • 在这个例子中,timerRef 用来存储计时器的 ID(一个可变的值)。即使 seconds 状态发生变化,timerRef 的值不会改变,它仅用来引用计时器。
  • useRef 允许我们避免因为 timerRef 的更新而导致不必要的组件重新渲染。

4. 用法 3:访问和持久化函数中的状态

有时你可能需要访问某个值的上一次状态。useRef 也能帮助我们存储一个值,在每次渲染时持久化下来,而不会因为它的改变导致重新渲染。

示例:记录上一个状态值

import React, { useState, useEffect, useRef } from 'react';const PreviousState = () => {const [count, setCount] = useState(0);const prevCountRef = useRef();useEffect(() => {prevCountRef.current = count;}, [count]); // 每次 `count` 变化时,更新 `prevCountRef`return (<div><h1>Current: {count}</h1><h2>Previous: {prevCountRef.current}</h2><button onClick={() => setCount(count + 1)}>Increment</button></div>);
};
  • 在这个例子中,prevCountRef 用来存储 count 的上一个值。每次 count 更新时,prevCountRef.current 会持有之前的值。
  • 由于 useRef 的特性,prevCountRef 的改变不会导致组件重新渲染,所以它不会影响性能。

5. useRef 与 useState 的区别

  • useState:用于存储需要在 UI 上表现出来的状态。每当你调用 setState 更新状态时,React 会重新渲染组件。
  • useRef:用于存储不需要触发重新渲染的状态。它的值是持久化的,不会随着组件的重新渲染而改变。

总结

  • useRef 的 .current 属性在组件的整个生命周期内都保持不变。因此,您可以将它作为持久化存储来引用外部资源、DOM 元素或者数据,而不必担心它会导致组件重新渲染。
  • 如果你将 useRef 用作数据存储时,不要把它当作普通的 React 状态来使用。因为如果你直接改变 useRef 的值(例如 ref.current = newValue),这不会触发渲染更新,因此当你需要依赖于 UI 更新时,应该使用 useState 或者 useReducer

二、useNavigate

useNavigate 是 React Router v6 中的一个 Hook,用于在函数组件中进行编程式的导航。通过 useNavigate,你可以在没有用户直接点击链接的情况下进行路由跳转。它通常与事件处理函数或条件逻辑一起使用。

1. 基础概念:

useNavigate 返回一个函数,允许你在代码中进行路由跳转。该函数接受一个路径(可以是字符串)或一个包含导航选项的对象,并将页面重定向到相应的路由。

语法:
const navigate = useNavigate();

然后,你可以使用 navigate 来触发导航:

navigate('/new-path'); // 跳转到指定路径
navigate(-1); // 跳转到上一个历史记录(类似浏览器的返回按钮)
navigate('/new-path', { replace: true }); // 跳转,并替换当前的历史记录

2. 常见用法:

示例 1:基本导航

import React from 'react';
import { useNavigate } from 'react-router-dom';const HomePage = () => {const navigate = useNavigate();const goToAbout = () => {navigate('/about'); // 编程式跳转到“/about”路径};return <button onClick={goToAbout}>Go to About</button>;
};

示例 2:带参数的导航

import React from 'react';
import { useNavigate } from 'react-router-dom';const UserProfile = () => {const navigate = useNavigate();const goToProfile = (userId) => {navigate(`/profile/${userId}`); // 跳转到具体用户的个人页面};return <button onClick={() => goToProfile(123)}>Go to User 123's Profile</button>;
};

此例演示了如何将动态路径作为参数传递给 navigate,从而跳转到用户特定的页面。

3. 导航选项:

navigate 还可以接收一个对象作为第二个参数,允许你设置一些额外的导航选项,比如是否替换历史记录,或者传递状态数据。

示例 3:使用导航选项

import React from 'react';
import { useNavigate } from 'react-router-dom';const LoginPage = () => {const navigate = useNavigate();const handleLogin = () => {// 登录成功后跳转到首页,并替换当前历史记录navigate('/', { replace: true });};return <button onClick={handleLogin}>Login</button>;
};
  • replace:如果设置为 true,则会替换当前历史记录,避免用户通过浏览器的“后退”按钮返回到此页面。
  • state:你还可以通过 state 传递一些状态数据,在导航后可以通过 location.state 访问这些数据。
navigate('/dashboard', { state: { from: 'login' } });

4. 后退和前进:

navigate 支持通过数字来实现类似浏览器历史记录的前进和后退操作。

示例 4:模拟浏览器的后退和前进

import React from 'react';
import { useNavigate } from 'react-router-dom';const NavigationButtons = () => {const navigate = useNavigate();return (<div><button onClick={() => navigate(-1)}>Back</button> {/* 后退 */}<button onClick={() => navigate(1)}>Forward</button> {/* 前进 */}</div>);
};
  • navigate(-1):后退一页,类似浏览器的“后退”按钮。
  • navigate(1):前进一页,类似浏览器的“前进”按钮。

5. 与其他 React Router 组件的结合使用:

useNavigate 可以与其他 React Router 组件(如 RouteLink 等)一起使用,来实现更复杂的导航逻辑。

示例 5:结合条件渲染导航

import React from 'react';
import { useNavigate } from 'react-router-dom';const ProtectedPage = ({ isAuthenticated }) => {const navigate = useNavigate();if (!isAuthenticated) {// 如果没有认证,重定向到登录页面navigate('/login', { replace: true });}return <div>Protected Content</div>;
};

在这个例子中,如果用户未认证,将会在渲染时进行跳转。

6. useNavigate 与 useHistory 的区别

  • useHistory:在 React Router v5 中使用,提供一个历史记录对象,用来进行导航。
  • useNavigate:在 React Router v6 中替代了 useHistory,提供了更加简洁的 API(没有历史对象,直接返回一个 navigate 函数)。

7. 总结:

  • useNavigate 是 React Router v6 提供的用于编程式导航的 Hook,它简化了路由跳转的方式。
  • 使用 navigate 函数,你可以轻松地进行路径跳转、替换历史记录、或者实现类似浏览器“后退”与“前进”的功能。
  • useNavigate 提供了更多灵活的导航选项,可以使路由管理更加精细和高效。

三、useLocation

useLocation 是 React Router 提供的一个钩子(hook),用于访问当前的浏览器位置对象。这可以让你获取当前的 URL 路径、查询参数、哈希值等信息,从而在函数组件中实现基于路由的动态渲染。

主要特性:

  1. 返回位置对象: useLocation 返回一个位置对象 (location),包含以下几个主要属性:

    • pathname: 当前 URL 的路径部分(例如:/home)。
    • search: 查询字符串(例如:?id=123&name=abc)。
    • hash: 哈希值(例如:#section1)。
    • state: 传递的状态对象,通常用于在页面间传递一些非 URL 参数的数据。
  2. 用途:

    • 在 React 应用中动态地根据当前路径或查询参数更新 UI。
    • 实现路由相关的逻辑,比如基于 URL 路径变化显示不同的内容。
  3. 示例:

    import { useLocation } from 'react-router-dom';function MyComponent() {const location = useLocation();return (<div><p>Current Path: {location.pathname}</p><p>Query String: {location.search}</p><p>Hash: {location.hash}</p></div>);
    }
    
  4. 动态更新: useLocation 会随着浏览器的 URL 变化自动更新。如果你想监听路由变化,可以依赖 location 对象的变化来触发重新渲染。

  5. useHistory 比较:

    • useHistory 主要用于程序化导航,通过访问历史对象来控制跳转。
    • useLocation 关注的是获取当前的位置信息,通常用于展示和路由状态的读取。

使用场景:

  • 根据 URL 查询参数改变页面内容。
  • 在某些页面上根据路径进行特定的 UI 展示(例如,导航栏高亮显示)。
  • 处理哈希路由或者与后端交互时,根据不同路径做动态数据加载。

四、useSearchParams

useSearchParams 是 React Router v6 中提供的一个钩子(hook),用于读取和修改 URL 中的查询参数(即 ?key=value 的部分)。与传统的 window.location.search 不同,useSearchParams 提供了更方便的方式来处理查询字符串,同时支持 React Router 的状态管理和自动更新。 

主要特性:

1.返回值: useSearchParams 返回一个数组,包含两个元素:

  • searchParams: 这是一个 URLSearchParams 对象,允许你读取、修改查询参数。
  • setSearchParams: 这是一个函数,允许你更新查询参数并触发 URL 更新。

2.URLSearchParams 对象:

searchParams 是一个 URLSearchParams 实例,提供了多种方法来操作查询字符串

  • get(name): 获取某个查询参数的值(例如:searchParams.get('id'))。
  • getAll(name): 获取某个查询参数的所有值(对于重复参数,返回一个数组)。
  • set(name, value): 设置某个查询参数的值。
  • has(name): 检查查询参数是否存在。
  • delete(name): 删除某个查询参数。

3.示例代码:

import { useSearchParams } from 'react-router-dom';function MyComponent() {// 获取当前的查询参数const [searchParams, setSearchParams] = useSearchParams();// 获取特定查询参数值const id = searchParams.get('id');const name = searchParams.get('name');// 修改查询参数const updateParams = () => {setSearchParams({ id: '456', name: 'John' });};return (<div><p>Current ID: {id}</p><p>Current Name: {name}</p><button onClick={updateParams}>Update Params</button></div>);
}

4.动态更新: useSearchParams 会随着查询参数的变化自动更新组件。如果查询参数发生变化,React 会重新渲染组件。你可以使用 searchParams 来读取当前查询字符串,使用 setSearchParams 来更新它。

5.更新查询参数: 当调用 setSearchParams 时,查询参数会被更新并触发页面的重新渲染。可以传递一个新的对象(例如 { id: '456', name: 'John' })来替换当前的查询参数,也可以传递一个函数来基于当前的查询参数进行更新。

setSearchParams(prev => {// 保留现有参数,修改某个字段prev.set('id', '456');return prev;
});

使用场景:

  • 控制分页和过滤器: 你可以利用查询参数(如 pagefilter)来控制内容的分页或筛选。
  • 分享链接: 在需要共享带有查询参数的链接时,useSearchParams 允许你动态地更改查询参数并更新 URL。
  • 维持 URL 状态: 在多个视图间保持查询参数一致,如在搜索功能中更新查询参数,以便用户刷新页面时仍然能看到相同的结果。

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

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

相关文章

.net core开发windows程序在国产麒麟操作系统中运行

.net core自从3.1版本号后&#xff0c;完全是一个独立的开源的多平台开发组件&#xff0c;目前国产化是趋势&#xff0c;不少项目需要开发国产如Kylin操作系统中运行的程序&#xff0c;无论是Web程序还是桌面程序&#xff0c;都有这样的需求。 首先&#xff0c;可明确的的.net…

基于 Python 的 Bilibili 评论分析与可视化

一、项目概述 本项目利用 Python 对 Bilibili &#xff08;哔哩哔哩&#xff09;平台上的视频评论数据进行爬取、清洗和分析&#xff0c;并通过可视化展示数据的主要特征。我们通过以下几个步骤实现了这一过程&#xff1a; 数据爬取&#xff1a;使用 Bilibili 提供的 API 获取…

Jenkins的pipeline Script的 每个组件的详细讲解

在Jenkins的Pipeline脚本中&#xff0c;各个组件的配置和Groovy的一些常用函数起到了决定性的作用&#xff0c;帮助开发人员控制自动化流程的执行。以下是对Jenkins Pipeline的主要组件和Groovy常用函数的详细讲解&#xff1a; 1. Jenkins Pipeline主要组件 1.1 agent 功能&…

基于碎纸片的拼接复原算法及MATLAB实现

一、问题描述 破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。传统上&#xff0c;拼接复原工作需由人工完成&#xff0c;准确率较高&#xff0c;但效率很低。特别是当碎片数量巨大&#xff0c;人工拼接很难在短时间内完成任务。随着计算…

如何禁用VMware虚拟网卡

安装VMWare虚拟机之后&#xff0c;会在本地创建两个虚拟网卡VMware Network Adapter VMnet1和VMware Network Adapter VMnet8&#xff0c;如果使用iNode客户端联网时会进行禁用多网卡检测&#xff0c;否则无法联网。因此&#xff0c;问题根源就在于虚拟网卡未禁用。 1、网络和…

ElasticSearch备考 -- Cross cluster replication(CCR)

一、题目 操作在cluster1&#xff08;local&#xff09;中操作索引task&#xff0c;复制到cluster2&#xff08;remote&#xff09;中 二、思考 CCR 我们可以对标MySQL 理解为为主从&#xff0c;后者备份。主节点负责写入数据&#xff0c;从/备节点负责同步时主节点的数据。 …

界面控件DevExpress WPF中文教程:TreeList视图及创建分配视图

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

基于Java的药店管理系统

药店管理系统 一&#xff1a;基本介绍开发环境管理员功能模块图系统功能部分数据库表设计 二&#xff1a;部分系统页面展示登录界面管理员管理进货信息界面管理员管理药品信息界面管理员管理员工界面管理员管理供应商信息界面管理员管理销售信息界面员工对信息进行管理员工对销…

策略模式、状态机详细解读

策略模式 (Strategy Pattern) 策略模式 (Strategy Pattern) 是一种行为型设计模式&#xff0c;旨在将一组算法封装成独立的类&#xff0c;使得它们可以相互替换。这种模式让算法的变化不会影响到使用算法的客户&#xff0c;减少了类之间的耦合。策略模式通常用于处理一类问题&…

Qwen2-VL:发票数据提取、视频聊天和使用 PDF 的多模态 RAG 的实践指南

概述 随着人工智能技术的迅猛发展&#xff0c;多模态模型在各类应用场景中展现出强大的潜力和广泛的适用性。Qwen2-VL 作为最新一代的多模态大模型&#xff0c;融合了视觉与语言处理能力&#xff0c;旨在提升复杂任务的执行效率和准确性。本指南聚焦于 Qwen2-VL 在三个关键领域…

探索Python的HTTP利器:Requests库的神秘面纱

文章目录 **探索Python的HTTP利器&#xff1a;Requests库的神秘面纱**一、背景&#xff1a;为何选择Requests库&#xff1f;二、Requests库是什么&#xff1f;三、如何安装Requests库&#xff1f;四、Requests库的五个简单函数使用方法1. GET请求2. POST请求3. PUT请求4. DELET…

信号保存和信号处理

目录 信号保存中重要的概念 内核中信号的保存 对sigset_t操作的函数 对block&#xff0c;pendding&#xff0c;handler三张表的操作 sigpromask ​编辑 sigpending 是否有sighandler函数呢&#xff1f; 案例 信号处理 操作系统是如何运行的&#xff1f; 硬件中断 …

基于HTTP编写ping操作

基于HTTP编写ping操作 前言 在上一集我们就完成了创建MockServer的任务&#xff0c;那么我们就可以正式开始进行网络的通讯&#xff0c;那么我们今天就来基于HTTP来做一个客户端ping服务端的请求&#xff0c;服务端返回pong的响应。 需求分析 基于HTTP&#xff0c;实现ping…

机器学习 贝叶斯公式

这是条件概率的计算公式 &#x1d443;(&#x1d434;|&#x1d435;)&#x1d443;(B|A)&#x1d443;(&#x1d434;)/&#x1d443;(&#x1d435;) 全概率公式 &#x1d443;(&#x1d435;)&#x1d443;(&#x1d435;|&#x1d434;)&#x1d443;(&#x1d434;)&am…

【ACM出版】第四届信号处理与通信技术国际学术会议(SPCT 2024)

第四届信号处理与通信技术国际学术会议&#xff08;SPCT 2024&#xff09; 2024 4th International Conference on Signal Processing and Communication Technology 2024年12月27-29日 中国深圳 www.icspct.com 重要信息 三轮征稿时间&#xff1a;2024年11月30日23:5…

【工具插件类教学】在 Unity 中使用 iTextSharp 实现 PDF 文件生成与导出

目录 一、准备工作 1. 安装 iTextSharp 2. 准备资源文件 二、创建 ExportPDFTool 脚本 1、初始化 PDF 文件,设置字体 2、添加标题、内容、表格和图片 三、使用工具类生成 PDF 四、源码地址 在 Unity 项目中,我们有时会需要生成带有文本、表格和图片的 PDF 文件,以便…

Java 责任链模式 减少 if else 实战案例

一、场景介绍 假设有这么一个朝廷&#xff0c;它有 县-->府-->省-->朝廷&#xff0c;四级行政机构。 这四级行政机构的关系如下表&#xff1a; 1、县-->府-->省-->朝廷&#xff1a;有些地方有完整的四级行政机构。 2、县-->府-->朝廷&#xff1a;直…

vue项目使用eslint+prettier管理项目格式化

代码格式化、规范化说明 使用eslintprettier进行格式化&#xff0c;vscode中需要安装插件ESLint、Prettier - Code formatter&#xff0c;且格式化程序选择为后者&#xff08;vue文件、js文件要分别设置&#xff09; 对于eslint规则&#xff0c;在格式化时不会全部自动调整&…

易考八股文之Elasticsearch合集

1、为什么要使用 Elasticsearch? 系统中的数据&#xff0c; 随着业务的发展&#xff0c; 时间的推移&#xff0c; 将会非常多&#xff0c;而业务中往往采用模糊查询进行数据的 搜索&#xff0c;而模糊查询会导致查询引擎放弃索引&#xff0c; 导致系统查询数据时都是全表扫描&…

Python 使用链式赋值

n n_ max(round(n * gd), 1) if n > 1 else n # depth gainPython 使用链式赋值将同一个值同时赋给多个变量。这意味着 n 和 n_ 会同时接收相同的结果值。我们可以将这行代码逐步拆解&#xff0c;以便理解传值的顺序和方法&#xff1a; 逐步解析 先计算右侧表达式的值&a…