当前位置: 首页 > 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.dtcms.com/a/341171.html

相关文章:

  • 继续记事本项目
  • 三轴云台之闭环反馈技术
  • MySQL数据库安全配置核心指南
  • 十二,数据结构-链表
  • BeyondWeb:大规模预训练合成数据的启示
  • 解决程序无响应自动重启
  • 高压柜无线测温:给智能化配电室装上“智能体温监测仪”
  • 前端基础知识操作系统系列 - 03(linux系统下 文件操作常用的命令有哪些)
  • C++ string(reserve , resize , insert , erase)
  • Clonezilla live 再生龙还原系统各个版本的不同
  • Sklearn 机器学习 房价预估 拆分训练集和测试集
  • Pydantic介绍(基于Python类型注解的数据验证和解析库)(BaseModel、校验邮箱校验EmailStr、BaseSettings)
  • SeaweedFS深度解析(五):裸金属集群部署(上)
  • Java 集合超详细教程
  • 循环神经网络(RNN)、LSTM 与 GRU (一)
  • 基于深度学习的订单簿异常交易检测与短期价格影响分析
  • 【深度学习】PyTorch中间层特征提取与可视化完整教程:从零开始掌握Hook机制与特征热力图
  • lua入门以及在Redis中的应用
  • 【ElasticSearch实用篇-03】QueryDsl高阶用法以及缓存机制
  • Java程序启动慢,DNS解析超时
  • 基于STM32的APP遥控视频水泵小车设计
  • K8S-Pod资源对象——标签
  • 【AI学习100天】Day08 使用Kimi每天问100个问题
  • 【指纹浏览器系列-绕过cdp检测】
  • 数据预处理:机器学习的 “数据整容术”
  • nginx-下载功能-状态统计-访问控制
  • 【数据结构】线性表——顺序表
  • 循环神经网络(RNN, Recurrent Neural Network)
  • Effective C++ 条款52:写了placement new也要写placement delete
  • 使用acme.sh自动申请AC证书,并配置自动续期,而且解决华为云支持问题,永久免费自动续期!