您的位置:首页 > 科技 > IT业 > 商丘网红打卡地_人力资源和社会保障部证书有哪些_简述网络营销的含义_百度搜索引擎网址

商丘网红打卡地_人力资源和社会保障部证书有哪些_简述网络营销的含义_百度搜索引擎网址

2025/4/21 19:10:36 来源:https://blog.csdn.net/chenlmw/article/details/147255612  浏览:    关键词:商丘网红打卡地_人力资源和社会保障部证书有哪些_简述网络营销的含义_百度搜索引擎网址
商丘网红打卡地_人力资源和社会保障部证书有哪些_简述网络营销的含义_百度搜索引擎网址

如果你是从 Vue 转到 React 的开发者,初见 useRef 可能会想:这不就是 React 版的 ref 吗?但真相是 —— 它能做的,比你想象得多得多。

👀 Vue 人初见 useRef

在 Vue 中,ref 是我们访问 DOM 或响应式数据的利器。但在 React 中,useRef 并不止是一个获取 DOM 的工具,它更像是一个“不会引起重新渲染的变量容器”。

如果你在想:

  • “为啥我改了 ref.current,界面却没更新?”
  • “这玩意儿跟 Vue 的 ref 好像不太一样?”
  • “它除了操作 DOM 还能干嘛?”

这篇文章,就帮你用 Vue 人的视角,彻底搞懂 useRef 的多种用法与常见陷阱。


🔍 什么是 useRef

引入 React 文档的话:

useRef 是一个 React Hook,它能帮助引用一个不需要渲染的值”

useRef 创建的是一个普通的 Javascript 对象,里面仅有一个 current 属性,用于读取和修改。

import { useRef } from "react";function Example() {const countRef = useRef(0);countRef.current += 1;
}

useRef 是一个 可变的盒子,你可以把任何值塞进去,它不会重新触发组件 render,但你可以随时取用。

🧪 举个栗子:
export default function Example() {const countRef = useRef(0);console.log("render");return (<button onClick={() => (countRef.current += 1)}>点击count:{countRef.current}</button>);
}

我们创建一个按钮去给 countRef 进行自增,我们看看组件有没有重新 render

在这里插入图片描述

可以看到,虽然 countRef 数据自增了,但是却不会 触发新的渲染

“当你希望组件“记住”某些信息,但又不想让这些信息 触发新的渲染 时,你可以使用 useRef

如果你比较熟悉 useState,我们可以举个更简单的例子:

import { useState } from "react";export default function Example() {const [countRef, never] = useState({ current: 0 });return (<button onClick={() => (countRef.current += 1)}>点击count:{countRef.current}</button>);
}

原则上 useRef 可以在 useState 的基础上实现:

不使用setup函数去改变值,不去触发新的渲染。

了解了基本概念,我们再来看看它与 Vue 的 ref 有哪些关键不同。

⚔️ useRef 和 Vue ref 的区别

对比点useRefVue ref
响应性不具备响应性,不触发 render具备响应性,数据变化会更新视图
使用场景DOM引用、缓存变量、定时器、历史值等DOM引用、响应式数据
数据结构{ current: value }value 是响应式对象
是否引发视图更新

Vue 的 ref响应式容器,值变化会自动更新视图;

而 React 的 useRef 更像一个可读写但不具响应性的变量盒子。

🧩 useRef 常见使用场景

前面介绍完 useRef 的基本概念和使用方法,我们接下来看看平时开发中比较常见的使用场景:

1. 定时器引用

我们来实现一个 简易计时器

import { useState, useRef } from "react";export default function Example() {const [time, setTime] = useState(0);const timerRef = useRef(null);const handleStart = () => {if (timerRef.current) return;const startTime = Date.now();timerRef.current = setInterval(() => {setTime(Date.now() - startTime);}, 10);};const handleStop = () => {if (!timerRef.current) return;clearInterval(timerRef.current);timerRef.current = null;console.log("销毁定时器:", timerRef.current);};return (<><h1>计时器: {time}</h1><button onClick={handleStart}>开始</button><button onClick={handleStop}>停止</button></>);
}
  • 按下开始键,计时器 开始进行计时,这时候把定时器存到 timerRef
  • 按下停止键,销毁当前定时器,防止出现 闭包导致的内存泄漏

在这里插入图片描述

2. 操作 DOM

我们假定一个场景,用户进入页面时,我们需要用户光标默认 聚焦到输入框

import { useEffect, useRef } from "react";export default function Example() {const inputRef = useRef(null);useEffect(() => {inputRef.current?.focus();}, []);return <input ref={inputRef} />;
}

我们需要:

  • 使用 useRef 创建 inputRef,默认值为 null
  • 使用 ref={inputRef} 去存储当前 DOM 元素。
  • 通过 useEffect 在进入页面时进行 inputRef.current?.focus()

这里类似 Vue 的 ref="xxx" + this.$refs.xxx.focus()

注意: 不要在渲染过程中读取或写入ref.current,会使ref变得不可预测。

在这里插入图片描述

使用 ref 去存储正常的标签都能正常获取其 DOM 元素,但是当你尝试将 ref 放在 自定义组件 上,会发生什么呢?

3. 绑定自定义组件的 ref

我们先来实践一下:

import { useEffect, useRef } from "react";function MyInput(props) {return <input {...props} />;
}export default function Example() {const inputRef = useRef(null);useEffect(() => {inputRef.current?.focus();}, []);return <MyInput ref={inputRef} />;
}

我们创建一个 MyInput 子组件,然后把 ref 绑定到我们子组件上。

控制台直接给我们弹了报错:

在这里插入图片描述

React 向控制台打印一条错误消息,提示我们如果想操控子组件,需要去使用 forwardRef API。

forwardRef 的用法

  • forwardRef表示允许子组件将其 DOM 节点放入 ref 中,默认情况下是不允许的。
  • forwardRef会让传入的子组件多一个 ref 作为第二个参数传入,用于存储当前 DOM 节点,第一个参数为 props

我们改进下:

const MyInput = forwardRef((props, ref) => {return <input {...props} ref={ref} />;
});

我们将 ref 绑定到 MyInput 组件中的 input,再来看看效果:

在这里插入图片描述

现在不会报错了,并且 input 框也正常 聚焦 了。


总结

  • useRef 用于存储值且不想去触发 render 的场景。
  • useRef 创建的值通过 .current 去进行 读取、修改
  • 常见用于存储 定时器、 DOM 节点
  • 存储自定义组件的 DOM 节点需配合 forwardRef API 使用。
  • 需要注意 不要在渲染过程中读取或写入 ref.current

如果你也是从 Vue 转过来的,看到这里可能已经对 useRef 有了更清晰的认知 —— 它并不是 Vue 的 ref 替代品,而是一种完全不同思路下的状态管理补充工具

希望这篇文章能帮你快速掌握 useRef,如果你觉得有帮助,别忘了点个赞👍或关注我后续的 重学 React 系列!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com