当前位置: 首页 > news >正文

CreateRef和useRef

文章目录

  • 1. 本质与使用场景
  • 2. 生命周期行为
  • 3. 功能范围

在 React 中,createRef 和 useRef 都是用于创建引用(ref)来访问 DOM 元素或组件实例的工具,但它们在 使用场景、生命周期行为 和 功能范围 上有显著区别。

1. 本质与使用场景

createRef
是一个 类组件和函数组件通用的 API,用于创建一个 ref 对象。
在 类组件 中,通常在 constructor 中初始化,通过 this.refName 访问。
在 函数组件 中可以直接使用,但每次渲染都会创建一个新的 ref 对象(可能导致不必要的更新)。

// 类组件中使用 createRef
class MyComponent extends React.Component {myRef = React.createRef();componentDidMount() {console.log(this.myRef.current); // 访问DOM元素}render() {return <div ref={this.myRef} />;}
}

useRef
是一个 仅用于函数组件的 Hook,不仅能创建 ref 对象,还能 保存任意可变值(类似类组件的 this)。
每次渲染返回 同一个 ref 对象(不会重新创建),避免了 createRef 在函数组件中重复创建的问题。
主要用于函数组件中访问 DOM 或存储跨渲染周期的可变数据。

// 函数组件中使用 useRef
function MyComponent() {const myRef = React.useRef(null);React.useEffect(() => {console.log(myRef.current); // 访问DOM元素}, []);return <div ref={myRef} />;
}

2. 生命周期行为

createRef
在函数组件中,每次组件重新渲染时,createRef 都会创建一个 新的 ref 对象。
这可能导致问题:例如在依赖 ref 的 useEffect 中,会因 ref 引用变化而触发不必要的副作用。

function BadExample() {// 每次渲染都会创建新的 ref 对象const myRef = React.createRef(); // 因 myRef 变化,每次渲染都会执行 useEffectReact.useEffect(() => {console.log(myRef.current); }, [myRef]); return <div ref={myRef} />;
}

useRef
在组件的整个生命周期中,useRef 返回的 ref 对象是 同一个(持久化的),不会随渲染重新创建。
这确保了 ref 引用的稳定性,避免了不必要的副作用触发。

function GoodExample() {// 整个生命周期中只创建一次 ref 对象const myRef = React.useRef(null); // 仅在组件挂载时执行一次(因 myRef 不变)React.useEffect(() => {console.log(myRef.current); }, [myRef]); return <div ref={myRef} />;
}

3. 功能范围

createRef
仅用于 创建 ref 对象,功能单一,其 current 属性主要用于关联 DOM 元素或组件。
useRef
除了创建 ref 访问 DOM 外,还可以 存储任意跨渲染周期的可变值(类似类组件的实例变量)。
因为 useRef 的 current 属性变化不会触发组件重新渲染,适合存储不需要引起 UI 更新的数据(如定时器 ID、上一次的状态值等)。

function TimerExample() {const timerRef = React.useRef(null); // 存储定时器IDconst startTimer = () => {timerRef.current = setInterval(() => {console.log('计时中...');}, 1000);};const stopTimer = () => {clearInterval(timerRef.current); // 跨渲染访问定时器ID};return (<div><button onClick={startTimer}>开始</button><button onClick={stopTimer}>停止</button></div>);
}
特性createRefuseRef
使用场景类组件为主,函数组件慎用仅用于函数组件
渲染时的创建行为每次渲染创建新对象(函数组件中)始终返回同一个对象(持久化)
功能范围仅创建 ref 访问 DOM创建 ref + 存储跨渲染的可变值
与 Hook 配合可能导致不必要的副作用触发适合与 useEffect 等 Hook 配合使用

最佳实践
类组件:使用 createRef。
函数组件:优先使用 useRef(既稳定又能扩展存储功能)。
避免在函数组件中使用 createRef,除非明确需要每次渲染创建新的 ref 对象(极少场景)。

//函数组件中使用createRef示例
import React from 'react';function CreateRefInFunction() {// 1. 使用createRef创建ref(每次渲染都会生成新对象)const inputRef = React.createRef();const logRef = React.createRef();// 2. 操作ref的函数(需在DOM挂载后调用)const handleFocus = () => {// 访问DOM元素:current属性指向关联的DOMinputRef.current?.focus();};const handleLog = () => {logRef.current.textContent = `输入值:${inputRef.current?.value || '空'}`;};// 3. 注意:每次渲染都会打印不同的ref对象(证明createRef每次创建新对象)console.log('当前渲染的ref对象:', inputRef);return (<div style={{ padding: 20 }}><h3>函数组件中使用createRef</h3><inputref={inputRef}type="text"placeholder="点击按钮聚焦"style={{ marginRight: 10 }}/><button onClick={handleFocus}>聚焦输入框</button><button onClick={handleLog} style={{ marginLeft: 10 }}>打印输入值</button><p ref={logRef} style={{ marginTop: 10 }}></p></div>);
}export default CreateRefInFunction;
http://www.lryc.cn/news/626747.html

相关文章:

  • Java内功修炼(2)——线程安全三剑客:synchronized、volatile与wait/notify
  • Web前端调试与性能优化,Charles抓包工具的高效应用
  • YOLOv11 到 C++ 落地全流程:ONNX 导出、NMS 判别与推理实战
  • Vue透传 Attributes(详细解析)2
  • 极其简单二叉树遍历JAVA版本
  • CMake1:概述
  • 查看磁盘占用情况和目录大小
  • 企业架构及战略价值
  • 如何让FastAPI任务系统在失败时自动告警并自我修复?
  • 从零实现自定义顺序表:万字详解 + 完整源码 + 图文分析
  • 从“怀疑作弊”到“实锤取证”:在线面试智能监考重塑招聘公信力
  • 河南萌新联赛2025第六场 - 郑州大学
  • 数据库优化提速(一)之进销存库存管理—仙盟创梦IDE
  • 开源模型应用落地-安全合规篇-深度合成隐式标识的技术实现(五)
  • 无人机感知系统详解
  • Tomcat 性能优化终极指南
  • C++ std::sort的应用总结
  • Vue2封装Axios
  • Google Chrome v139.0.7258.139 便携增强版
  • 嵌入式音频开发(3)- AudioService核心功能
  • 嵌入式开发学习———Linux环境下网络编程学习(四)
  • 04-认证授权服务开发指南
  • 读《精益数据分析》:规模化(Scale)—— 复制成功,进军新市场
  • Kafka如何保证消费确认与顺序消费?
  • Python爬虫实战:研究dark-fantasy,构建奇幻文学数据采集分析系统
  • GitHub宕机生存指南:从应急协作到高可用架构设计
  • BM25 vs TF-IDF:经典文本检索方法的对比
  • 《算法导论》第 34 章 - NP 完全性
  • RK Android14 新建分区恢复出厂设置分区数据不擦除及开机动画自定义(二)
  • 细说数仓中不同类型的维度