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

  • 让一个按钮自动获得焦点
  • 点击按钮让某个元素滚动到视图中
  • 获取某个元素的高度
相关推荐
向下的大树20 小时前
npm 最新镜像,命令导致下载错误
前端·npm·node.js
宁雨桥20 小时前
Service Worker:前端离线化与性能优化的核心技术
前端·性能优化
IT_陈寒20 小时前
SpringBoot实战:这5个隐藏技巧让我开发效率提升200%,90%的人都不知道!
前端·人工智能·后端
ObjectX前端实验室21 小时前
【图形编辑器架构】节点树与渲染树的双向绑定原理
前端·计算机图形学·图形学
excel21 小时前
Vue2 与 Vue3 生命周期详解与对比
前端
一只猪皮怪51 天前
React 18 前端最佳实践技术栈清单(2025版)
前端·react.js·前端框架
Misnice1 天前
React渲染超大的字符串
前端·javascript·react.js
天天向上的鹿茸1 天前
用矩阵实现元素绕不定点旋转
前端·线性代数·矩阵
李鸿耀1 天前
主题换肤指南:设计到开发的完整实践
前端
带娃的IT创业者1 天前
TypeScript + React + Ant Design 前端架构入门:搭建一个 Flask 个人博客前端
前端·react.js·typescript