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

React Refs 完整使用指南

React Refs 完整使用指南

1. Refs 基础用法

1.1 创建和访问 Refs

// 类组件中使用 createRef
class MyComponent extends React.Component {constructor(props) {super(props);this.myRef = React.createRef();}componentDidMount() {// 访问 DOM 节点console.log(this.myRef.current);}render() {return <div ref={this.myRef}>Hello</div>;}
}// 函数组件中使用 useRef
function MyFunctionComponent() {const myRef = useRef(null);useEffect(() => {// 访问 DOM 节点console.log(myRef.current);}, []);return <div ref={myRef}>Hello</div>;
}

1.2 回调 Refs

class CallbackRefComponent extends React.Component {setTextInputRef = (element) => {this.textInput = element;};focusTextInput = () => {// 直接使用原生 DOM APIif (this.textInput) this.textInput.focus();};render() {return (<><input type="text" ref={this.setTextInputRef} /><button onClick={this.focusTextInput}>Focus the text input</button></>);}
}

2. Refs 常见用途

2.1 管理焦点

function FocusInput() {const inputRef = useRef(null);useEffect(() => {// 组件挂载时自动聚焦inputRef.current.focus();}, []);return (<div><input ref={inputRef} type="text" /><button onClick={() => inputRef.current.focus()}>Focus Input</button></div>);
}

2.2 文本选择

function TextSelection() {const textRef = useRef(null);const selectText = () => {if (textRef.current) {textRef.current.select();}};return (<div><inputref={textRef}type="text"defaultValue="Click to select me"/><button onClick={selectText}>Select Text</button></div>);
}

2.3 媒体控制

function VideoPlayer() {const videoRef = useRef(null);const handlePlay = () => {videoRef.current.play();};const handlePause = () => {videoRef.current.pause();};return (<div><video ref={videoRef}><source src="video.mp4" type="video/mp4" /></video><button onClick={handlePlay}>Play</button><button onClick={handlePause}>Pause</button></div>);
}

3. Refs 转发

3.1 基本 Ref 转发

const FancyButton = React.forwardRef((props, ref) => (<button ref={ref} className="fancy-button">{props.children}</button>
));// 使用转发的 ref
function Parent() {const buttonRef = useRef(null);useEffect(() => {console.log(buttonRef.current); // 访问 button DOM 节点}, []);return <FancyButton ref={buttonRef}>Click me!</FancyButton>;
}

3.2 高阶组件中的 Ref 转发

function withLogger(WrappedComponent) {class LoggerComponent extends React.Component {componentDidUpdate(prevProps) {console.log('Props updated', prevProps, this.props);}render() {const {forwardedRef, ...rest} = this.props;return <WrappedComponent ref={forwardedRef} {...rest} />;}}return React.forwardRef((props, ref) => {return <LoggerComponent {...props} forwardedRef={ref} />;});
}// 使用高阶组件
const ButtonWithLogger = withLogger(FancyButton);

4. Refs 与函数组件

4.1 useImperativeHandle 使用

const FancyInput = React.forwardRef((props, ref) => {const inputRef = useRef(null);useImperativeHandle(ref, () => ({focus: () => {inputRef.current.focus();},getValue: () => {return inputRef.current.value;},setValue: (value) => {inputRef.current.value = value;}}));return <input ref={inputRef} />;
});// 使用自定义 ref 方法
function Parent() {const inputRef = useRef(null);const handleClick = () => {inputRef.current.focus();inputRef.current.setValue('Hello!');console.log(inputRef.current.getValue());};return (<div><FancyInput ref={inputRef} /><button onClick={handleClick}>Manipulate Input</button></div>);
}

5. Refs 的高级用法

5.1 多个 Refs 管理

function MultipleRefs() {const refs = useRef({});const setRef = (id) => (element) => {refs.current[id] = element;};const focusRandom = () => {const keys = Object.keys(refs.current);const randomKey = keys[Math.floor(Math.random() * keys.length)];refs.current[randomKey]?.focus();};return (<div><input ref={setRef('input1')} placeholder="Input 1" /><input ref={setRef('input2')} placeholder="Input 2" /><input ref={setRef('input3')} placeholder="Input 3" /><button onClick={focusRandom}>Focus Random Input</button></div>);
}

5.2 条件性 Refs

function ConditionalRef() {const [showInput, setShowInput] = useState(true);const inputRef = useRef(null);useEffect(() => {if (showInput) {inputRef.current?.focus();}}, [showInput]);return (<div><button onClick={() => setShowInput(!showInput)}>Toggle Input</button>{showInput && <input ref={inputRef} />}</div>);
}

6. Refs 最佳实践

6.1 避免过度使用

// 不推荐
function BadExample() {const divRef = useRef(null);const updateContent = () => {// 不推荐直接操作 DOMdivRef.current.innerHTML = 'Updated content';};return <div ref={divRef}>Content</div>;
}// 推荐
function GoodExample() {const [content, setContent] = useState('Content');return <div>{content}</div>;
}

6.2 清理 Refs

function CleanupExample() {const timerRef = useRef(null);useEffect(() => {timerRef.current = setInterval(() => {console.log('Tick');}, 1000);// 清理定时器return () => {clearInterval(timerRef.current);};}, []);return <div>Timer Example</div>;
}

7. 总结

Refs 使用要���:

  1. 适用场景:

    • DOM 元素的直接操作
    • 媒体播放控制
    • 文本选择和焦点管理
    • 第三方 DOM 库的集成
  2. 注意事项:

    • 避免过度使用 Refs
    • 优先使用声明式编程
    • 及时清理 Refs 资源
    • 谨慎使用 Refs 操作 DOM
  3. 性能考虑:

    • Refs 更新不会触发重新渲染
    • 适当使用可以避免不必要的渲染
    • 大量 Refs 可能影响内存使用
  4. 开发建议:

    • 优先使用 React 的声明式 API
    • 只在必要时使用 Refs
    • 使用 TypeScript 增加类型安全
    • 保持代码的可维护性
      </rewritten_file>

相关文章:

React Refs 完整使用指南

React Refs 完整使用指南 1. Refs 基础用法 1.1 创建和访问 Refs // 类组件中使用 createRef class MyComponent extends React.Component {constructor(props) {super(props);this.myRef React.createRef();}componentDidMount() {// 访问 DOM 节点console.log(this.myRef…...

程控电阻箱应用中需要注意哪些安全事项?

程控电阻箱是一种用于精确控制电路中电流和电压的电子元件&#xff0c;广泛应用于电子实验、测试设备以及精密测量仪器中。在应用程控电阻箱时&#xff0c;为确保安全和设备的正常运行&#xff0c;需要注意以下几个安全事项&#xff1a; 1. 正确连接&#xff1a;确保电阻箱与电…...

C/C++基础知识复习(43)

1) 什么是运算符重载&#xff1f;如何在 C 中进行运算符重载&#xff1f; 运算符重载是指在 C 中为现有的运算符定义新的行为&#xff0c;使得它们能够用于用户定义的数据类型&#xff08;如类或结构体&#xff09;。通过运算符重载&#xff0c;可以让自定义类型像内置数据类型…...

苍穹外卖-day05redis 缓存的学习

苍穹外卖-day05 课程内容 Redis入门Redis数据类型Redis常用命令在Java中操作Redis店铺营业状态设置 学习目标 了解Redis的作用和安装过程 掌握Redis常用的数据类型 掌握Redis常用命令的使用 能够使用Spring Data Redis相关API操作Redis 能够开发店铺营业状态功能代码 功能实…...

VSCode搭建Java开发环境 2024保姆级安装教程(Java环境搭建+VSCode安装+运行测试+背景图设置)

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。—— 苏轼《水调歌头》 创作者&#xff1a;Code_流苏(CSDN) 目录 一、Java开发环境搭建二、VScode下载及安装三、VSCode配置Java环境四、运行测试五、背景图设置 很高兴你打开了这篇博客&#xff0c;更多详细的安装教程&…...

PHP MySQL 插入多条数据

PHP MySQL 插入多条数据 在Web开发中&#xff0c;PHP和MySQL的组合是非常常见的。PHP是一种服务器端脚本语言&#xff0c;而MySQL是一种流行的数据库管理系统。在许多情况下&#xff0c;我们可能需要一次性向MySQL数据库插入多条数据。这可以通过几种不同的方法实现&#xff0…...

Oracle安装报错:将配置数据上载到资料档案库时出错

环境&#xff1a;联想服务器 windows2022安装Oracle11g 结论&#xff1a;禁用多余网卡先试试&#xff0c;谢谢。 以下是问题描述和处理过程&#xff1a; 网上处理方式: hosts文件添加如下&#xff1a; 关闭防火墙 暂时无法测试通过。 发现ping不是本地状态&#xff0c;而是…...

JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)

目录 JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能&#xff0c;JS中排序算法的使用详解&#xff08;附实际应用代码&#xff09; 一、为什么要使用Array.sort() 二、Array.sort() 的使用与技巧 1、基础语法 2、返回值 3、…...

Deformable DETR:Deformable Transformers for End-to-End Object Detection论文学习

1. 为什么提出了Deformable DETR&#xff1f; 因为DETR本身的计算量大&#xff0c;收敛速度慢。其次是小目标检测效果差。主要原因是Attention模块每次只关注一小部分采样点&#xff0c;导致需要很多轮数才能学习到真实需要关注的目标。 Deformable DETR注意力模块只关注一个…...

机器学习-43-可解释性机器学习库LIME

文章目录 1 LIME1.1 LIME的特点1.2 LIME的步骤2 应用LIME2.1 分类模型2.1.1 创建模型和解释器2.1.2 解释样本2.2 回归模型2.2.1 创建模型和解释器2.2.2 解释样本2.3 文本模型2.3.1 创建模型和解释器2.3.2 解释样本2.4 图像模型2.4.1 创建模型和解释器2.4.2 解释样本3 附录3.1 l…...

【Unity功能集】TextureShop纹理工坊(五)选区

项目源码&#xff1a;在终章发布 索引 选区PS选区选区功能点提炼 TextureShop选区方形区域中间镂空边框的流动虚线SelectedRegion类选择选区更新选区 选区 选区&#xff0c;也既是在当前选中图层中&#xff0c;已选择的编辑区域&#xff0c;我们后续的所有图像编辑操作&#x…...

Spring Cloud OpenFeign快速入门demo

一、应用场景 Spring Cloud OpenFeign 是一个声明式的 HTTP 客户端&#xff0c;旨在简化微服务之间的通信。它使得开发者能够通过简单的接口定义和注解来调用 RESTful API&#xff0c;极大地减少了样板代码。以下是一些典型的应用场景&#xff1a; 微服务间调用&#xff1a;在…...

研发效能DevOps: Vite 使用 Element Plus

目录 一、实验 1.环境 2.初始化前端项目 3.安装 vue-route 4.安装 pinia 5.安装 axios 6.安装 Element Plus 7.gitee创建工程 8. 配置路由映射 9.Vite 使用 Element Plus 二、问题 1.README.md 文档推送到gitee未自动换行 2.访问login页面显示空白 3.表单输入账户…...

sfnt-pingpong -测试网络性能和延迟的工具

sfnt-pingpong 是一个用于测试网络性能和延迟的工具&#xff0c;通常用于测量不同网络环境下的数据包传输性能、吞吐量、延迟等指标。 它通常是基于某种网络协议&#xff08;如 TCP&#xff09;执行“ping-pong”式的测试&#xff0c;即客户端和服务器之间相互发送数据包&…...

Kubernetes、Docker 和 Docker Registry 关系是是什么?

Kubernetes&#xff08;常简称为 k8s&#xff09;、Docker 和 Docker Registry 是现代云原生应用中三个关键的组件&#xff0c;它们各自承担不同的职责&#xff0c;但在容器化部署和管理过程中紧密协作。以下是它们之间关系的详细解释&#xff1a; 一、核心概念简介 1. Docker…...

docker部署微信小程序自动构建发布和更新

通过 Jenkins 和 Docker 部署微信小程序&#xff0c;并实现自动构建、发布和版本更新&#xff0c;主要涉及以下几个步骤&#xff1a; 设置 Jenkins 环境配置 GitLab 与 Jenkins 的集成构建 Docker 镜像部署和发布微信小程序配置 Jenkins 自动构建 以下是详细的步骤说明&#…...

模仿elementui的Table,实现思路

vue2子组件使用render&#xff0c;给子子组件插槽传值 和elementui的Table一样使用render 在 Vue 2 中&#xff0c;子组件使用render函数向子子组件插槽传值可以通过以下步骤实现&#xff1a; 1、创建子组件 首先创建一个子组件&#xff0c;在子组件中使用render函数来渲染内容…...

Unity中使用环形缓冲区平滑抖动值

环形缓冲数据结构&#xff0c;就是如下图一样的一个收尾相接的列表 在index指针指到4时&#xff0c;再往里添加数据&#xff0c;index就会指向0&#xff0c;并覆盖已有数据。 如何绘制Sin函数&#xff0c;请看下面一篇文章 Unity中如何实现绘制Sin函数图像-CSDN博客 接下来要…...

【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?

文章目录 前言问题描述问题分析问题解决1.允许所有用户上传驱动文件2.如果是想只上传白名单的驱动 前言 该方法适合永洪BI系列产品&#xff0c;包括不限于vividime desktop&#xff0c;vividime z-suit&#xff0c;vividime x-suit产品。 问题描述 当我们连接数据源的时候&a…...

SpringBoot使用 AOP 实现自定义日志记录并保存在Mysql

本文主要介绍在 Spring Boot 中使用 AOP 实现自定义日志记录并保存在 Mysql 的方法。先阐述记录日志的重要性及传统方式的弊端&#xff0c;提出新方式&#xff0c;即通过创建自定义注解、切面类等&#xff0c;将重要日志存到数据库&#xff0c;还给出了创建日志表、注解类、切面…...

【数据结构与算法】第38篇:图论(二):深度优先搜索(DFS)与广度优先搜索(BFS)

一、图遍历的基本概念1.1 为什么需要遍历和树一样&#xff0c;图也需要一种方式“访问”所有顶点。但图可能有环&#xff0c;所以需要标记已访问的顶点&#xff0c;避免重复访问。1.2 两种遍历方式遍历方式核心思想数据结构DFS一条路走到底&#xff0c;回溯栈&#xff08;递归&…...

Office Custom UI Editor终极指南:免费打造专属Office界面

Office Custom UI Editor终极指南&#xff1a;免费打造专属Office界面 【免费下载链接】office-custom-ui-editor Standalone tool to edit custom UI part of Office open document file format 项目地址: https://gitcode.com/gh_mirrors/of/office-custom-ui-editor …...

别再死记硬背了!用Python代码复现Photoshop 27种混合模式(附完整源码)

用Python代码实现Photoshop混合模式的终极指南 在数字图像处理领域&#xff0c;Photoshop的混合模式就像魔术师的调色板&#xff0c;能够创造出令人惊叹的视觉效果。但你是否想过这些看似神秘的混合效果背后&#xff0c;其实是一系列精确的数学公式在起作用&#xff1f;本文将带…...

Linux持久化配置GRE接口

Centos7持久化配置GRE接口GRE协议简介前置条件1.开发ipv4转发1.1启用TCP窗口缩放1.2启用自动MTU1.3禁用ipv6--可选1.4使内核配置生效2.加载内核模块3.放通防火墙方案1:ip命令临时配置GRE隧道VM1临时配置GRE接口配置邻居启动GRE隧道VM2临时配置GRE接口配置邻居启动GRE隧道关闭和…...

从零到爬取:在Linux服务器(CentOS 7)上用Anaconda部署你的第一个Scrapy爬虫

从零到爬取&#xff1a;在Linux服务器&#xff08;CentOS 7&#xff09;上用Anaconda部署你的第一个Scrapy爬虫 当你第一次通过SSH连接到一台全新的CentOS 7服务器时&#xff0c;面对那个闪烁的光标&#xff0c;可能会感到一丝茫然。不同于Windows的图形界面&#xff0c;Linux服…...

避坑指南:Windows/Linux下Java串口通信库RXTX与jSerialComm选型及配置详解

Java串口通信库选型实战&#xff1a;RXTX与jSerialComm的工业级应用对比 工业自动化领域对串口通信的需求从未减弱&#xff0c;尤其在RS485设备控制、传感器数据采集等场景中。作为Java开发者&#xff0c;面对RXTX和jSerialComm这两个主流选择时&#xff0c;如何根据项目特点做…...

HunyuanVideo-Foley问题解决:常见部署错误与解决方案汇总

HunyuanVideo-Foley问题解决&#xff1a;常见部署错误与解决方案汇总 1. 镜像简介与环境准备 HunyuanVideo-Foley是由腾讯混元团队开发的开源视频音效生成模型&#xff0c;能够智能分析视频内容并自动匹配电影级音效。本镜像封装了完整的运行环境&#xff0c;支持一键部署使用…...

千问3.5-9B代码审查自动化:定位Bug与安全漏洞检测

千问3.5-9B代码审查自动化&#xff1a;定位Bug与安全漏洞检测 1. 为什么需要自动化代码审查 在软件开发过程中&#xff0c;代码审查是保证质量的重要环节。但传统的人工审查方式面临几个痛点&#xff1a;首先&#xff0c;资深工程师的时间成本太高&#xff0c;每个pull reque…...

为什么AutoDL平台选择Ubuntu作为统一系统镜像?

1. 为什么AutoDL平台清一色选择Ubuntu&#xff1f; 第一次用AutoDL平台的朋友可能会发现一个有趣的现象&#xff1a;所有系统镜像清一色都是Ubuntu&#xff0c;从18.04到20.04再到22.04版本。这不禁让人好奇&#xff0c;为什么一个专业的AI计算平台会如此专一地选择Ubuntu&…...

MySQL 常用数据类型的系统总结

一、数值型&#xff08;存储数字&#xff0c;含整数、小数、布尔值&#xff09;1. 整数类型&#xff08;INT 系列&#xff09;数据类型字节数取值范围&#xff08;有符号&#xff09;取值范围&#xff08;无符号&#xff09;核心特性适用场景TINYINT1-128 ~ 1270 ~ 255占用空间…...