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

useref原理

​useRef 的原理是:React 在内部通过 Hook 链表机制,在每次组件渲染时都返回同一个 ref 对象({ current }),这个对象的值可以随意修改且不会触发重新渲染,常用于保存 DOM 引用或跨渲染周期的变量。​

✅ 一、useRef 是什么?

是一个React Hook,返回一个具有 .current属性的可变对象,用于存储可变值或 DOM 引用

const ref = useRef(initialValue);
  • 返回一个 ​​可变对象​​,其结构为:{ current: initialValue }

  • 你可以通过 ref.current读取或修改它的值

  • ​修改 .current不会触发组件重新渲染​

  • ​在组件的多次渲染之间,ref 对象本身保持不变(引用不变)​

常用于:

  • 获取 DOM 元素引用

  • 保存可变值(如定时器 ID、上一次的值)而​​不引起渲染​


✅ 二、useRef 的核心原理

🎯 核心思想一句话:

​useRef 是 React 提供的一个 Hook,它在每次组件渲染时,都返回同一个 ref 对象(引用不变),这个对象的 .current 属性是可变的,但修改它不会触发重新渲染。​


1️⃣ ​​useRef 返回的是一个稳定的对象引用(每次渲染返回同一个对象)​

React 在内部实现 useRef时,会:

  • ​在组件首次渲染时,创建一个普通的 JavaScript 对象:{ current: initialValue }

  • ​将该对象保存在 React 内部的 Hook 链表中(与当前组件关联)​

  • ​在后续每次重新渲染时,React 都会返回同一个 ref 对象(即内存地址不变)​

✅ 这就是为什么你可以在多次渲染中拿到同一个 ref对象,且可以放心地用它存一些“长期不变”的数据或 DOM 引用。

为什么返回稳定对象引用?

React 内部在 Hook 链表中保存了该 ref 对象,每次渲染都返回同一个引用,不会新建


2️⃣ ​​修改 .current不会触发重新渲染​

React 的渲染机制是:

  • 当调用 ​​状态设置函数(如 setState、useReducer、useContext 变化)​​ 时,React 知道状态发生了变化,就会安排一次 ​​重新渲染

  • 但 ​​useRef 的 .current 是一个普通属性,React 不会监听它的变化,也不会因为它的改变而触发重新渲染​

✅ 所以,无论你如何修改 ref.current,React 都​​不会重新执行组件函数​​,页面也不会刷新。


3️⃣ ​​useRef 的实现依赖 React 内部的 Hook 机制​

React 的每一个 ​​Hook(如 useState、useEffect、useRef)​​ 都是按照 ​​调用顺序​​ 保存在 ​​当前组件 Fiber 节点上的一个单向链表(Hook链表)​​ 中的。

当组件重新渲染时,React 会:

  • 按照 ​​Hook 的调用顺序​​,从链表中依次取出上一次渲染时保存的 Hook 状态

  • 对于 useRef,React 会返回上一次创建的那个 { current: ... }对象,而不是新建一个

✅ 这就是为什么 useRef在多次渲染中始终返回同一个对象 —— 因为 React 内部复用了那个 Hook 对象。


✅ 三、useRef 的简单实现原理(伪代码 / 概念模型)

虽然我们无法看到 React 源码的细节,但可以用伪代码来模拟它的行为:

// 假设这是 React 内部管理 Hook 的方式(简化模型)let hookChain = []; // Hook 链表,按调用顺序保存每次渲染的 Hook 状态function useRef(initialValue) {// 获取当前 Hook 的索引(React 内部通过调用顺序管理)const hookIndex = getCurrentHookIndex(); // 如果是第一次渲染,创建一个新的 ref 对象if (!hookChain[hookIndex]) {hookChain[hookIndex] = { current: initialValue }; // 创建 ref 对象}// 每次渲染都返回同一个 ref 对象return hookChain[hookIndex];
}

✅ 每次调用 useRef(),React 都会从内部保存的 Hook 数据中,返回你​​上一次用过的那个 ref 对象​​,而不是新建一个。

所以无论你调用多少次 useRef(),只要没有卸载组件,你拿到的都是 ​​同一个对象引用​​。


✅ 四、useRef 与 useState 的对比(原理层面)

特性

​useRef​

​useState​

​返回值​

一个对象:{ current: any }

一个数组:[state, setState]

​修改方式​

直接修改 .current属性

调用 setState(newValue)

​是否会触发重新渲染?​

❌ 不会

✅ 会

​React 是否追踪其变化?​

❌ 不追踪,不关心

✅ 追踪,一旦变化就触发更新

​底层保存方式​

保存为普通的 Hook 对象,每次返回同一个引用

保存状态值,变化时触发调度与渲染

​用途​

保存 DOM 引用、可变值(不触发渲染)

保存 UI 相关状态(触发渲染)


✅ 五、深入一点:React Fiber 与 Hook 链表(高级)

在 React 内部的实现中:

  • 每个 ​​函数组件​​ 对应一个 ​​Fiber 节点​

  • 每个 ​​Hook(如 useRef、useState)​​ 被调用时,会按照顺序保存到该 Fiber 节点上的一个 ​​Hook 链表(链表结构)​​ 中

  • 每个 Hook 在链表中是一个对象,保存了该 Hook 的状态与逻辑

  • 当组件重新渲染时,React 会 ​​按顺序遍历这个 Hook 链表​​,恢复上一次渲染的 Hook 状态

✅ 所以 useRef能够返回同一个对象,是因为 React 内部在 Fiber 上 ​​持久化了该 Hook 的引用​​,而不是每次渲染都新建。


✅ 六、总结:useRef 的原理和creactref区别

问题

原理说明

​useRef 是什么?​

React Hook,返回一个具有 .current属性的可变对象,用于存储可变值或 DOM 引用

​为什么每次渲染返回同一个 ref 对象?​

React 内部在 Hook 链表中保存了该 ref 对象,每次渲染都返回同一个引用,不会新建

​修改 .current会触发重新渲染吗?​

❌ 不会,React 不监听 .current 的变化,它只是一个普通属性

​useRef 的底层依赖是什么?​

React 的 Fiber 架构 + Hook 链表机制,保证每次渲染能正确恢复上一次的 Hook 状态

​useRef 和 useState 有什么本质区别?​

useState 的状态变化会触发重新渲染,而 useRef 的 .current 变化不会

http://www.dtcms.com/a/428794.html

相关文章:

  • 德惠市建设局网站WordPress面包屑主题
  • flask做的网站 网址青浦专业网站建设
  • 开闭原则详解(OCP)
  • Javaweb(servlet深入)
  • 小九源码-springboot067-Java兰州市出租车服务管理系统
  • 专业做网站照片广告网站设计
  • spring框架做网站wordpress禁主题
  • 801-203_各无人机厂家对RemoteID支持情况汇总
  • 网站实例往届生做网站编辑
  • 深圳市住房建设局网站首页建设网站需要哪些人员
  • seo网站关键词优化费用杭州做网站设计公司
  • 如何做可以微信转发的网站建设官方网站企业登录
  • IPFS技术介绍:探索去中心化存储的未来
  • wordpress 调用中等图片扬州抖音seo
  • 现在流行用什么做网站务川县住房和城乡建设局网站
  • 做网站需要先申请域名百度链接提交地址
  • 万年县建设银行网站拼音全称池州做网站
  • 济南网站建设流程广告设计与制作专业就业方向
  • 【LangChain】P3 Model IO 模块详解:模型调用与参数配置指南
  • 公司网站备案查询网站建设问题清单
  • 石家庄城乡建设局网站6建企业网站 硬件
  • Spring cache整合Redis
  • 网站做伪静态知识付费微网站开发
  • 【从零开始java学习|第二十一篇】包装类是干嘛的
  • 网站建设运营协议书子公司网站备案
  • 晋江市建设招投标网站自己怎么制作网页游戏
  • 衡水建立网站关键词排名优化易下拉稳定
  • 国外网站建设软件排行榜h5快速建站
  • 长沙 php企业网站系统一个公司可以备案几个网站
  • 基本信息型网站有哪些爱做网站免费模板vip