当前位置: 首页 > news >正文

React第十七章(useRef)

useRef

当你在React中需要处理DOM元素或需要在组件渲染之间保持持久性数据时,便可以使用useRef。

import { useRef } from 'react';
const refValue = useRef(initialValue)
refValue.current // 访问ref的值 类似于vue的ref,Vue的ref是.value,其次就是vue的ref是响应式的,而react的ref不是响应式的

通过Ref操作DOM元素

参数
  • initialValue:ref 对象的 current 属性的初始值。可以是任意类型的值。这个参数在首次渲染后被忽略。
返回值
  • useRef返回一个对象,对象的current属性指向传入的初始值。 {current:xxxx}
注意
  • 改变 ref.current 属性时,React 不会重新渲染组件。React 不知道它何时会发生改变,因为 ref 是一个普通的 JavaScript 对象。
  • 除了 初始化 外不要在渲染期间写入或者读取 ref.current,否则会使组件行为变得不可预测。
import { useRef } from "react"
function App() {//首先,声明一个 初始值 为 null 的 ref 对象let div = useRef(null)const heandleClick = () => {//当 React 创建 DOM 节点并将其渲染到屏幕时,React 将会把 DOM 节点设置为 ref 对象的 current 属性console.log(div.current)}return (<>{/*然后将 ref 对象作为 ref 属性传递给想要操作的 DOM 节点的 JSX*/}<div ref={div}>dom元素</div><button onClick={heandleClick}>获取dom元素</button></>)
}
export default App

数据存储

我们实现一个保存count的新值和旧值的例子,但是在过程中我们发现一个问题,就是num的值一直为0,这是为什么呢?

因为等useStateSetCount执行之后,组件会重新rerender,num的值又被初始化为了0,所以num的值一直为0。

import React, { useLayoutEffect, useRef, useState } from 'react';function App() {let num = 0let [count, setCount] = useState(0)const handleClick = () => {setCount(count + 1)num = count;};return (<div><button onClick={handleClick}>增加</button><div>{count}:{num}</div></div>);
}export default App;

在这里插入图片描述

如何修改?

我们可以使用useRef来解决这个问题,因为useRef只会在初始化的时候执行一次,当组件reRender的时候,useRef的值不会被重新初始化。

import React, { useLayoutEffect, useRef, useState } from 'react';function App() {let num = useRef(0)let [count, setCount] = useState(0)const handleClick = () => {setCount(count + 1)num.current = count;};return (<div><button onClick={handleClick}>增加</button><div>{count}:{num.current}</div></div>);
}export default App;

在这里插入图片描述

实际应用

我们实现一个计时器的例子,在点击开始计数的时候,计时器会每300ms执行一次,在点击结束计数的时候,计时器会被清除。

问题

我们发现,点击end的时候,计时器并没有被清除,这是为什么呢?

原因

这是因为组件一直在重新ReRender,所以timer的值一直在被重新赋值为null,导致无法清除计时器。

import React, { useLayoutEffect, useRef, useState } from 'react';function App() {console.log('render')let timer: NodeJS.Timeout | null = nulllet [count, setCount] = useState(0)const handleClick = () => {timer = setInterval(() => {setCount(count => count + 1)}, 300)};const handleEnd = () => {console.log(timer);if (timer) {clearInterval(timer)timer = null}};return (<div><button onClick={handleClick}>开始计数</button><button onClick={handleEnd}>结束计数</button><div>{count}</div></div>);
}export default App;
如何修改?

我们可以使用useRef来解决这个问题,因为useRef的值不会因为组件的重新渲染而改变。

import React, { useLayoutEffect, useRef, useState } from 'react';function App() {console.log('render')let timer = useRef<null | NodeJS.Timeout>(null)let [count, setCount] = useState(0)const handleClick = () => {timer.current = setInterval(() => {setCount(count => count + 1)}, 300)};const handleEnd = () => {if (timer.current) {clearInterval(timer.current)timer.current = null}};return (<div><button onClick={handleClick}>开始计数</button><button onClick={handleEnd}>结束计数</button><div>{count}</div></div>);
}export default App;

注意事项

  1. 组件在重新渲染的时候,useRef的值不会被重新初始化。

  2. 改变 ref.current 属性时,React 不会重新渲染组件。React 不知道它何时会发生改变,因为 ref 是一个普通的 JavaScript 对象。

  3. useRef的值不能作为useEffect等其他hooks的依赖项,因为它并不是一个响应式状态。

  4. useRef不能直接获取子组件的实例,需要使用forwardRef。

相关文章:

React第十七章(useRef)

useRef 当你在React中需要处理DOM元素或需要在组件渲染之间保持持久性数据时&#xff0c;便可以使用useRef。 import { useRef } from react; const refValue useRef(initialValue) refValue.current // 访问ref的值 类似于vue的ref,Vue的ref是.value&#xff0c;其次就是vu…...

React第十五节useReducer使用详解差异

useReducer() 的用法注意事项 1、 概述&#xff1a; useReducer() 常用于管理复杂的状态更新逻辑&#xff0c;特别是在状态更新依赖于多个条件或动作时&#xff0c;useReducer 提供了一种更加结构化和可维护的方式来处理状态。可以将更新函数写在组件外面 它与 useState() 相…...

NanoLog起步笔记-5-客户端简要描述

nonolog起步笔记-5-客户端简要描述 客户端的简要的设计图路notify模式服务端最好分两个核 NanoLog::setLogLevel(NOTICE);从 NANO_LOG 开始NANO_LOGcompiling time的语句getNumNibblesNeeded&#xff1a;得到prompt中&#xff0c;number的数量countFmtParams&#xff1a;得到所…...

Flink:入门介绍

目录 一、Flink简介 2.1 Flink 架构 2.2 Flink 应用程序 运行模式 二、Flink 集群 部署 2.1 本地集群模式 2.1.1 安装JDK​编辑 2.1.2 下载、解压 Flink 2.1.3 启动集群 2.1.4 停止集群 2.2 Standalone 模式 2.2.0 集群规划 2.2.1 安装JDK 2.2.2 设置免密登录 2…...

目标跟踪领域经典论文解析

亲爱的小伙伴们&#x1f618;&#xff0c;在求知的漫漫旅途中&#xff0c;若你对深度学习的奥秘、JAVA 、PYTHON与SAP 的奇妙世界&#xff0c;亦或是读研论文的撰写攻略有所探寻&#x1f9d0;&#xff0c;那不妨给我一个小小的关注吧&#x1f970;。我会精心筹备&#xff0c;在…...

网络编程 | TCP套接字通信及编程实现经验教程

1、TCP基础铺垫 TCP/IP协议簇中包含了如TCP、UDP、IP、ICMP、ARP、HTTP等通信协议。TCP协议是TCP/IP协议簇中最为常见且重要的通信方式之一&#xff0c;它为互联网上的数据传输提供了可靠性和连接管理。 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议…...

SAP导出表结构并保存到Excel 源码程序

SAP导出表结构并保存到Excel,方便写代码时复制粘贴 经常做接口,需要copy表结构,找到了这样一个程程,特别有用。 01. 先看结果...

Linux下redis环境的搭建

1.redis的下载 redis官网下载redis的linux压缩包&#xff0c;官网地址:Redis下载 网盘链接&#xff1a; 通过网盘分享的文件&#xff1a;redis-5.0.4.tar.gz 链接: https://pan.baidu.com/s/1cz3ifYrDcHWZXmT1fNzBrQ?pwdehgj 提取码: ehgj 2.redis安装与配置 将包上传到 /…...

REDMI瞄准游戏赛道,推出小屏平板

近日&#xff0c;REDMI推出了一款8.8英寸的小屏平板&#xff0c;引发市场关注。该平板采用LCD屏幕&#xff0c;搭载天玑9400处理器&#xff0c;定位游戏市场&#xff0c;意在开拓小屏平板的新领域‌。 ‌小屏平板新尝试‌ 这款REDMI平板未追随大屏潮流&#xff0c;而是选择了8…...

springai结合ollama

目录 ollama 介绍 使用 下载&#xff1a; 安装&#xff1a; 点击这个玩意next就行了。 运行 spring ai使用ollama调用本地部署的大模型 加依赖 配置yml 写代码 ollama 介绍 官网&#xff1a;Ollama Ollama是一个用于部署和运行各种开源大模型的工具&#xff1b; …...

React第十三节开发中常见问题之(视图更新、事件处理)

一、视图更新有哪些方案&#xff1f; useState用法介绍 1、对于数据变量 正常的增删改查&#xff0c;只会让数据更新&#xff0c;但是不会触发 React 视图的更新&#xff1b; 如&#xff1a; <script lang"jsx">const baseTable [{name:Andy, age: 18, id…...

【Appium报错】安装uiautomator2失败

目录 1、通过nmp安装uiautomator2&#xff1a;失败 2、通过 Appium 的平台直接安装驱动程序 3、通过pip 来安装 uiautomator2 1、通过nmp安装uiautomator2&#xff1a;失败 我先是通过npm安装的uiautomator2&#xff0c;也显示已经安装成功了&#xff1a; npm install -g …...

DataSophon集成CMAK KafkaManager

本次集成基于DDP1.2.1 集成CMAK-3.0.0.6 设计的json和tar包我放网盘了. 通过网盘分享的文件&#xff1a;DDP集成CMAK 链接: https://pan.baidu.com/s/1BR70Ajj9FxvjBlsOX4Ivhw?pwdcpmc 提取码: cpmc CMAK github上提供了zip压缩包.将压缩包解压之后 在根目录下加入启动脚本…...

Ubuntu22.04深度学习环境安装【显卡驱动安装】

前言 使用Windows配置环境失败&#xff0c;其中有一个包只有Linux版本&#xff0c;Windows版本的只有python3.10的&#xff0c;所以直接选用Linux来配置环境&#xff0c;显卡安装比较麻烦&#xff0c;单独出一期。 显卡驱动安装 方法一&#xff1a;在线安装&#xff08;操作…...

21届秋/校招面经

开篇先说一下我自身情况&#xff0c;东南大学本科计算机科学与技术专业毕业&#xff0c;gpa3.2/4.8。零零散散搞过一年多ACM&#xff0c;去年&#xff08;2019&#xff09;在icpc上海站拿了铜之后增加了信心&#xff08;因为当时训练总时间半年不到&#xff09;&#xff0c;于是…...

相机动态/在线标定

图1 图2 基本原理 【原理1】平行线在射影变换后会交于一点。如图所示,A为相机光心,蓝色矩形框为归一化平面,O为平面中心。地面四条黄色直线为平行且等距的车道线。HI交其中两条车道线于H、I, 过G作HI的平行线GM交车道线于M。HI、GM在归一化平面上的投影分别为JK、PN,二者会…...

MySQL 8.0 新特性汇总

文章目录 前言1. 运维管理 1.1 可持久化变量1.2 管理员端口1.3 资源组1.4 数据库粒度只读1.5 show processlist 实现方式1.6 加速索引创建速度1.7 控制连接的内存使用量1.8 克隆插件1.9 mysqldump 新增参数1.10 慢日志增强1.11 快速加列1.12 InnoDB 隐藏主键1.13 Redo 配置1.14…...

Resnet C ++ 部署 tensort 部署(四)

Resnet C 部署 pytorch功能测试&#xff08;一&#xff09; Resnet C 部署 模型训练&#xff08;二&#xff09; Resnet C 部署 模型测试&转 onnx&#xff08;三&#xff09; Resnet C 部署 tensort 部署&#xff08;四&#xff09; 之后&#xff0c;开始onnx 转trt 部…...

《Java核心技术I》对并发散列映射的批操作

对并发散列映射的批操作 Java API提供了批处理&#xff0c;计时其他线程处理映射&#xff0c;这些操作也能安全的执行。 3种不同操作&#xff1a; search(搜索)&#xff0c;为每个键或值应用一个函数&#xff0c;直到函数生成一个非null的结果&#xff0c;然后搜索终止&…...

记录一次使用git无权限的问题排查

正常的配置了公私钥之后&#xff0c;在gitlab中也存储了配对的公钥&#xff0c;但当使用git clone 时&#xff0c;总是报无权限 由于在这台机器中添加了多个公私钥&#xff0c;有点复杂&#xff0c;我们可以使用命令 ssh -vvvT 调试一下 ssh -vvvT yourGitlabAddr...

开发者专属配置:OpenClaw+GLM-4-7-Flash优化命令行工作效率

开发者专属配置&#xff1a;OpenClawGLM-4-7-Flash优化命令行工作效率 1. 为什么开发者需要AI增强命令行&#xff1f; 作为每天与终端打交道的开发者&#xff0c;我经常遇到这样的困境&#xff1a;忘记复杂的grep参数组合、需要反复查阅历史命令、或是面对一长串docker compo…...

从单张图片到实时视频流:给RK3588上的YOLOv11推理Demo加个OpenCV‘外挂’

从单张图片到实时视频流&#xff1a;RK3588上YOLOv11与OpenCV的高效整合实战 当开发者首次在RK3588上成功运行YOLOv11的静态图片推理时&#xff0c;那种成就感往往伴随着新的渴望——如何让这个模型"活"起来&#xff1f;本文将带你突破单帧测试的局限&#xff0c;通过…...

Superpowers 系统学习笔记:AI编程Agent的完整开发方法论

Superpowers 系统学习笔记:AI编程Agent的完整开发方法论 声明: 📝 作者:甜城瑞庄的核桃(ZMJ) 原创学习笔记,欢迎分享,但请保留作者信息及原文链接哦~ 项目地址:https://github.com/obra/superpowers Star数:36.6K+(持续增长中) 工具作者:Jesse Vincent (@obra) …...

深入解析UniApp中的package.json:从基础配置到高级技巧

1. 初识UniApp中的package.json 第一次接触UniApp项目时&#xff0c;我盯着package.json文件看了半天&#xff0c;心想这不就是个管理npm包依赖的配置文件吗&#xff1f;直到踩了几个坑才发现&#xff0c;UniApp对这个文件做了特殊扩展&#xff0c;让它成为了项目配置的中枢神经…...

Qwen-Image-2512部署教程:阿里云/腾讯云轻量服务器512MB内存精简部署方案

Qwen-Image-2512部署教程&#xff1a;阿里云/腾讯云轻量服务器512MB内存精简部署方案 1. 前言&#xff1a;像素艺术生成新选择 你是否遇到过这样的困扰&#xff1a;想要创作独特的像素风格作品&#xff0c;却苦于没有专业的美术功底&#xff1f;或者需要为游戏开发快速生成大…...

中考真题资源合集

2024版《万唯中考真题分类》合集 文件大小: 2.2GB内容特色: 2024版万唯中考真题按考点分类&#xff0c;全科覆盖适用人群: 初三学生、教师、家长陪读备考核心价值: 刷透真题&#xff0c;精准查漏补缺&#xff0c;冲刺高分下载链接: https://pan.quark.cn/s/73347caeee74 2026…...

C语言中结构体指针如何用 -> 取子数据及链表应用示例

在C语言当中&#xff0c;指针箭头“->”看起来是简单的&#xff0c;然而&#xff0c;好多人在学到链表之际&#xff0c;会被它难住。此符号从本质上来说&#xff0c;那是从一个结构体指针里把内部数据取出的快捷途径&#xff0c;要理解它呀&#xff0c;得先弄明白变量、指针…...

数据科学好帮手:OpenClaw+GLM-4.7-Flash自动化分析工作流

数据科学好帮手&#xff1a;OpenClawGLM-4.7-Flash自动化分析工作流 1. 为什么需要自动化数据科学工作流 作为一个经常处理数据的人&#xff0c;我发现自己80%的时间都花在了重复性劳动上&#xff1a;清洗数据、生成基础可视化、写分析报告。每次开始一个新项目&#xff0c;都…...

Android定位模拟技术全解析:基于系统级Hook的位置伪造实现方案

Android定位模拟技术全解析&#xff1a;基于系统级Hook的位置伪造实现方案 【免费下载链接】FakeLocation Xposed module to mock locations per app. 项目地址: https://gitcode.com/gh_mirrors/fak/FakeLocation 在移动应用开发与测试过程中&#xff0c;精准控制定位信…...

OpenClaw故障模拟:Qwen3.5-4B-Claude在异常操作场景下的恢复能力

OpenClaw故障模拟&#xff1a;Qwen3.5-4B-Claude在异常操作场景下的恢复能力 1. 为什么需要测试AI助手的故障恢复能力 上周我在用OpenClaw自动整理项目文档时&#xff0c;亲眼目睹了一场"数字灾难"——脚本误删了正在编辑的Markdown文件&#xff0c;而我没有开启版…...