别再怕 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,比如:

  • 让一个按钮自动获得焦点
  • 点击按钮让某个元素滚动到视图中
  • 获取某个元素的高度
相关推荐
索西引擎23 分钟前
浅谈 Vue 的双向数据绑定
前端·vue.js
iku_ki32 分钟前
axios二次封装-单个、特定的实例的拦截器、所有实例的拦截器。
运维·服务器·前端
断竿散人43 分钟前
前端救急实战:用 patch-package 解决 vue-pdf 电子签章不显示问题
前端·webpack·npm
蓝倾43 分钟前
淘宝获取商品分类接口操作指南
前端·后端·fastapi
十盒半价1 小时前
深入理解 React 中的 useState:从基础到进阶
前端·react.js·trae
ccc10181 小时前
前端性能优化实践:深入理解懒加载的实现与最佳方案
前端
CodeTransfer1 小时前
今天给大家搬运的是四角线框hover效果
前端·vue.js
归于尽1 小时前
别让类名打架!CSS 模块化教你给样式上 "保险"
前端·css·react.js
凤凰AI1 小时前
Python知识点4-嵌套循环&break和continue使用&死循环
开发语言·前端·python
Lazy_zheng1 小时前
虚拟 DOM 到底是啥?为什么 React 要用它?
前端·javascript·react.js