react的useRef 作用:获取DOM、保存可变数据、区别 createRef

useRef 是 React 中非常常用的 Hook,核心特点:

在组件多次渲染之间保存一个可变值,并且修改它不会触发重新渲染。

主要有三个用途:获取 DOM、保存可变数据、和 createRef 的区别。


1. 获取 DOM 元素(最常见)

类似 Vue 的 ref

例子:获取 input 并自动聚焦

复制代码
import { useRef, useEffect } from "react";

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

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return (
    <input ref={inputRef} />
  );
}

执行流程:

复制代码
首次渲染
↓
inputRef = { current: null }

DOM挂载完成
↓
React自动赋值
inputRef.current = input节点

useEffect执行
↓
focus()

此时:

复制代码
inputRef.current

得到:

复制代码
<input>

常见用途:

复制代码
获取元素高度
获取滚动位置
focus()
播放视频
canvas操作
上传文件

例如:

复制代码
divRef.current.scrollIntoView();
videoRef.current.play();

2. 保存可变数据(不会触发重新渲染)

这是很多人忽略但很重要的用途。

假设统计点击次数:

用 state

复制代码
const [count, setCount] = useState(0);

修改:

复制代码
setCount(count + 1);

会重新渲染。


用 ref

复制代码
const countRef = useRef(0);

function add() {
    countRef.current++;
    console.log(countRef.current);
}

修改:

复制代码
countRef.current++;

不会重新 render。

适合保存:

复制代码
定时器ID
上一次值
缓存数据
防抖timer
socket实例
请求状态

例:

保存 setTimeout:

复制代码
const timerRef = useRef(null);

useEffect(() => {
  timerRef.current = setTimeout(() => {
      console.log("执行");
  },1000);

  return () => {
      clearTimeout(timerRef.current);
  }
},[])

避免:

复制代码
组件销毁
timer丢失
内存泄漏

3. 获取上一次值(经典面试题)

记录前一个 state:

复制代码
function App() {
  const [count,setCount]=useState(0);
  const prevRef=useRef();

  useEffect(()=>{
      prevRef.current=count;
  },[count])

  return (
      <>
          当前:{count}
          上次:{prevRef.current}
      </>
  )
}

效果:

复制代码
当前:3
上次:2

因为:

复制代码
render
↓
useEffect
↓
更新 ref

4. useRef 与 createRef 区别(面试高频)

createRef

复制代码
class App extends React.Component {
    inputRef = React.createRef();
}

主要给 类组件 用。

函数组件里:

复制代码
const ref = createRef();

问题:

每次 render 都会重新创建:

复制代码
render1
ref = {}

render2
ref = {}

不是同一个对象。


useRef

复制代码
const ref = useRef();

只创建一次:

复制代码
render1
ref={current:null}

render2
还是同一个ref

不会变。

所以函数组件推荐:

复制代码
函数组件 → useRef
类组件 → createRef

对比表:

区别 useRef createRef
适用 函数组件 类组件
是否重新创建
保存值 可以 不适合
获取DOM 支持 支持
触发渲染 不触发 不触发

总结一句:

复制代码
useRef =
获取DOM
+ 保存跨渲染可变值
+ 不触发更新
+ 函数组件替代 createRef

前端面试里经常问:

useRef 为什么修改 current 不会触发更新?

因为 React 不会追踪 ref.current 的变化,它只是普通对象:

复制代码
{
   current: xxx
}

修改对象属性,不会进入 React 的状态更新流程。

相关推荐
Csvn18 分钟前
🧩「找不到模块」排查全记录——Monorepo 下 TypeScript 路径别名的 5 种「不通」与根治方案
前端
腻害兔25 分钟前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程
CodexDave41 分钟前
MySQL事务隔离级别与MVCC机制解析
前端·数据库·mysql·nginx·性能优化·负载均衡
Ai_easygo2 小时前
AI Agent开发入门——从ReAct到Tool Calling,拆解Agent的底层运行逻辑
前端·人工智能·react.js
研☆香2 小时前
分析制作html页面,如何划分页面结构
前端
腻害兔2 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:支付模块 yudao-module-pay,一个让产品经理都看懂的支付中台设计
java·前端·vue.js·产品经理·ai编程
kyriewen2 小时前
我扒了最近的前端面经——2026年面试不背八股文了,考这5样
前端·面试·ai编程
IT_陈寒2 小时前
Redis的持久化配置把我坑惨了:你以为数据安全了?
前端·人工智能·后端
小徐_23333 小时前
uni-app 项目别再从零搭了!3 个 Wot UI 起手模板怎么选?
前端·uni-app
张元清3 小时前
React useResizeObserver Hook:追踪元素尺寸变化(2026)
javascript·react.js