别再怕 useRef 了!一篇文章讲清楚它和 DOM 的关系

前面讲了react中的几个Hooks:

useStateuseEffect juejin.cn/post/752292...

useLayoutEffectjuejin.cn/post/752836...

今天我们再来认识一个 Hook:

在 React 开发中,我们经常需要与 DOM 元素打交道,比如让输入框自动聚焦、获取元素的位置、滚动页面等。这时,React 提供了一个非常有用的工具 ------ useRef,它可以帮助我们"记住"某个 DOM 元素的位置,并对其进行操作。

这篇文章将用通俗的语言和生活化的例子,带你理解:

  • useRef 是什么?
  • useRef 和 DOM 有什么关系?
  • ref 属性的作用是什么?
  • 如何用 useRef 操作 DOM?

🧑‍🏫 什么是 useRef

useRef 是 React 提供的一个 Hook,它的作用是创建一个 "引用"对象 ,这个对象在整个组件的生命周期中保持不变

基本语法

jsx 复制代码
import { useRef } from 'react';
jsx 复制代码
const ref = useRef(initialValue);
  • initialValue:初始值,可以是任意类型(如数字、字符串、对象、函数等)。
  • 返回一个对象:{ current: initialValue },通过 .current 属性访问或修改值。

格式是这样的:

js 复制代码
{ current: initialValue }

示例:

jsx 复制代码
const countRef = useRef(0);
console.log(countRef.current); // 输出 0
countRef.current = 5;
console.log(countRef.current); // 输出 5

重要特性

🤔 什么是"组件的生命周期"?

简单回顾一下,组件的生命周期就是从它被创建、显示在页面上,到它被更新,最后从页面上消失的整个过程;简单来说就是,从出生、长大到死亡的过程。

在这个过程中,当状态发生变化时组件可能会多次重新渲染。

但是:

  • 每次重新渲染时,函数组件中的变量会"重置",但 useRef 创建的对象不会。
  • 它就像一个"盒子",React 保证它在整个生命周期中始终指向同一个对象。

举个通俗的例子:

想象你在一家公司工作,公司给你一个"工牌",上面写着你的名字和员工编号。

  • 员工编号 = useRef 创建的对象(在整个工作期间都不会变)
  • 你的职位、工资、工位 = 组件中的其他变量(可能会经常变化)

即使你换了职位、换了工位,你的员工编号还是不变的。

一句话总结:

useRef 就像是一个"永远不会丢的笔记本",我们可以在组件的整个生命周期中用它来记录和访问一些值,即使组件重新渲染了,它也始终在那里。

如何用 useRef 操作 DOM?

我们来看一个常见的例子:让输入框自动聚焦

jsx 复制代码
import React, { useRef, useEffect } from 'react';

function TextInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus(); // 组件挂载后自动聚焦
  }, []);

  return <input ref={inputRef} type="text" />;
}

代码解释

jsx 复制代码
const inputRef = useRef(null);

这行代码相当于我们准备了一张空白的便签本(inputRef),上面还没写东西(初始值是 null)。

jsx 复制代码
<input ref={inputRef} />

这行代码的意思是:

" React,等你把这个 <input> 渲染成真正的 DOM 后,请你把它的地址写在这张便签本上(inputRef)。"

这样我们之后就可以通过 inputRef.current 来操作这个 <input> 的 DOM 了。

jsx 复制代码
  useEffect(() => {
    inputRef.current.focus(); // 组件挂载后自动聚焦
  }, []);

这段代码的意思是:

" 等组件渲染完成后,请找到这个 input 元素,让它自动获得焦点。"

总结一下 ref 属性的作用:

说法 通俗解释
ref 是 React 的一个特殊属性 它可以让你"拿到"某个 DOM 元素的真实引用
ref={inputRef} 把这个 DOM 的地址写在 inputRef 这个便签本上
inputRef.current 通过这个属性访问真实的 DOM 元素

⚠️ 小提醒:不要滥用 ref

虽然 useRef 可以操作 DOM,但在 React 中我们要尽量避免直接操作 DOM,除非真的需要(比如聚焦、动画、第三方库集成等)。
React 更推荐使用状态(如 useState)来驱动 UI 的变化。

常见的 DOM 操作(通过 useRef 实现)

操作 示例代码
自动聚焦 inputRef.current.focus()
获取 DOM 位置 inputRef.current.getBoundingClientRect()
滚动到某个元素 inputRef.current.scrollIntoView()
修改样式 inputRef.current.style.color = "red"
获取输入框的值(不推荐) inputRef.current.value

结语

希望这篇文章能帮你彻底理解 useRef 和 DOM 的关系。如果你是初学者,建议多写几个小例子练习使用 useRef,比如:

  • 让一个按钮自动获得焦点
  • 点击按钮让某个元素滚动到视图中
  • 获取某个元素的高度
相关推荐
oil欧哟13 小时前
🧐 我用 Vibe Coding 从 0 到 1 打造 AI 产品,上线一个月效果如何?有什么心得?
前端·产品·vibecoding
霍克itxt点top14 小时前
NestJS 入门到实战 前端必学服务端新趋势无密分享
前端
xiguolangzi14 小时前
1panel web服务部署
前端
摘星编程14 小时前
Cursor Pair Programming:在前端项目里用 AI 快速迭代 UI 组件
前端·人工智能·ui·typescript·前端开发·cursorai
醉方休14 小时前
React Fiber 风格任务调度库
前端·javascript·react.js
保卫大狮兄14 小时前
连锁零售企业如何能更有效地管理门店考勤?
面试·职场和发展
北辰alk14 小时前
React Intl 全方位解析:为你的 React 应用注入国际化灵魂
前端
李白白i单身版14 小时前
前端VUE项目实现静默打印,无需用户手动确认
前端
bysking14 小时前
【29 - git bisect】git bisect 命令进行二分定位,排查异常commit bysking
前端
华仔啊15 小时前
摸鱼神器!前端大佬私藏的 11 个 JS 神级 API,复制粘贴就能用,效率翻倍
前端·javascript