news 2026/8/2 6:50:32

React获取DOM元素全解析:掌握Refs与Hook核心用法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
React获取DOM元素全解析:掌握Refs与Hook核心用法

一、React中获取DOM元素的背景与核心思想

1.1 为什么需要获取DOM元素

React的核心思想是声明式渲染与虚拟DOM, 通常情况下我们不需要直接操作真实DOM。但在某些特定场景下, 我们仍然需要直接获取真实的DOM节点来进行命令式操作。这些场景包括但不限于: (1) 管理焦点, 文本选择或媒体播放; (2) 触发强制动画; (3) 集成第三方DOM库 (如D3.js, Chart.js等)。

1.2 Refs的核心概念与工作流程

React提供了Refs来访问真实DOM节点或React组件实例。Refs是一个可变对象, 其current属性被初始化为传入的初始值。当Ref被挂载到DOM节点上时, React会将该节点的引用赋值给ref.current; 当组件卸载时, React会将其重置为null。以下是Refs工作流程的直观展示:

创建Ref对象

将ref属性绑定到JSX节点

React挂载组件

将DOM节点赋值给ref.current

通过ref.current访问DOM

执行命令式操作

1.3 获取DOM元素的几种主流方式

在React中获取DOM元素主要有以下几种主流方式: (1) 函数组件中使用useRef Hook; (2) 类组件中使用React.createRef; (3) 使用回调Refs; (4) 使用forwardRef转发Ref给子组件。下面我们将逐一详细展开。

二、函数组件中获取DOM元素

2.1 使用useRef Hook创建Ref对象

在函数组件中, 获取DOM元素最推荐的方式是使用useRef Hook。useRef返回一个可变的ref对象, 其current属性被初始化为传入的参数。具体操作步骤如下:

  1. 引入useRef并创建ref对象。
  2. 将ref对象绑定到DOM元素的ref属性。
  3. 在事件处理函数中通过ref.current访问真实DOM。

代码示例如下:

import React, { useRef } from 'react'; function TextInput() { const inputRef = useRef(null); const focusInput = () => { inputRef.current.focus(); }; return ( <div> <input ref={inputRef} type="text" /> <button onClick={focusInput}>聚焦输入框</button> </div> ); }

2.2 useRef结合回调与副作用操作

有时我们需要在组件挂载后立即对DOM元素进行测量或操作, 这时可以结合useEffect使用。操作步骤如下:

  1. 创建ref对象并绑定到目标DOM。
  2. 在useEffect的回调函数中访问ref.current。
  3. 执行如获取宽度等DOM测量操作。

代码示例如下:

import React, { useRef, useEffect } from 'react'; function MeasureBox() { const divRef = useRef(null); useEffect(() => { if (divRef.current) { const width = divRef.current.getBoundingClientRect().width; console.log('DOM元素宽度:', width); } }, []); return <div ref={divRef} style={{ width: '100px', height: '100px', backgroundColor: 'skyblue' }}>测量我</div>; }

2.3 函数组件中转发Ref (forwardRef)

默认情况下, 函数组件没有实例, 因此无法直接通过ref属性获取函数组件内部的DOM。如果需要让父组件获取子函数组件内的DOM, 需要使用React.forwardRef进行转发。操作步骤如下:

  1. 使用React.forwardRef包裹子函数组件。
  2. 将传入的ref参数绑定到子组件内部的DOM元素。
  3. 在父组件中创建ref并传递给子组件。

代码示例如下:

import React, { useRef, forwardRef } from 'react'; const CustomInput = forwardRef((props, ref) => { return <input ref={ref} type="text" placeholder={props.placeholder} />; }); function ParentComponent() { const childRef = useRef(null); const handleClick = () => { childRef.current.focus(); }; return ( <div> <CustomInput ref={childRef} placeholder="请输入" /> <button onClick={handleClick}>聚焦子组件输入框</button> </div> ); }

三、类组件中获取DOM元素

3.1 使用React.createRef获取DOM

在类组件中, 推荐使用React.createRef来创建Ref对象。操作步骤如下:

  1. 在构造函数中通过React.createRef()创建ref对象。
  2. 将ref对象绑定到render方法返回的DOM元素上。
  3. 在componentDidMount等生命周期中通过this.myRef.current访问DOM。

代码示例如下:

import React, { Component } from 'react'; class AutoFocusInput extends Component { constructor(props) { super(props); this.inputRef = React.createRef(); } componentDidMount() { this.inputRef.current.focus(); } render() { return <input ref={this.inputRef} type="text" />; } }

3.2 使用回调Refs获取DOM

回调Refs是另一种获取DOM的方式。操作步骤如下:

  1. 编写一个接收DOM节点作为参数的函数。
  2. 将该函数作为ref属性传递给DOM元素。
  3. 在函数内部将DOM节点存储到组件实例的属性上以供后续使用。

代码示例如下:

import React, { Component } from 'react'; class CallbackRefInput extends Component { constructor(props) { super(props); this.setInputRef = element => { this.inputElement = element; }; } componentDidMount() { if (this.inputElement) { this.inputElement.focus(); } } render() { return <input ref={this.setInputRef} type="text" />; } }

3.3 类组件中Ref的传递与层级访问

在类组件中, 如果父组件需要访问子组件内部的DOM节点, 操作步骤如下:

  1. 父组件创建ref对象并传递给子组件的ref属性。
  2. 子组件如果是类组件, 父组件获取的ref将指向子组件实例。
  3. 父组件通过ref.current调用子组件暴露的方法, 间接操作子组件内部的DOM。

代码示例如下:

import React, { Component } from 'react'; class ChildInput extends Component { constructor(props) { super(props); this.state = { value: '' }; } focus = () => { this.input.focus(); } render() { return <input ref={el => this.input = el} type="text" />; } } class ParentForm extends Component { constructor(props) { super(props); this.childRef = React.createRef(); } handleClick = () => { this.childRef.current.focus(); } render() { return ( <div> <ChildInput ref={this.childRef} /> <button onClick={this.handleClick}>调用子组件方法</button> </div> ); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/2 6:48:23

逆向工程中的编码与加密算法识别与实战分析

1. 从“看热闹”到“看门道”&#xff1a;逆向中的编码与加密刚入门逆向那会儿&#xff0c;我总盯着那些花里胡哨的算法库和复杂的汇编跳转&#xff0c;觉得那才是“真功夫”。后来踩坑踩多了才明白&#xff0c;真正卡住新手脖子的&#xff0c;往往不是那些高深的虚拟机保护或者…

作者头像 李华
网站建设 2026/8/2 6:42:59

30B开源模型登顶科研榜:揭秘AI科研助手部署与微调实战

1. 项目概述&#xff1a;当30B开源模型站上科研之巅最近AI圈里有个事儿挺有意思&#xff0c;一个叫UniPat AI的团队&#xff0c;带着他们30B参数规模的开源模型&#xff0c;冲上了OpenAI搞的那个科研榜单的榜首。这事儿一出&#xff0c;不少朋友跑来问我&#xff0c;这“30B”到…

作者头像 李华
网站建设 2026/8/2 6:42:12

具身大模型空间智能评估新范式:从理论到实践的全面解析

1. 项目概述&#xff1a;一场关于智能“身体”的深度体检最近在ICLR 2024上看到一篇论文&#xff0c;标题是“李曼玲、李飞飞、吴佳俊等联手&#xff1a;评估具身大模型的新范式&#xff01;”&#xff0c;业内朋友讨论得挺多。简单来说&#xff0c;这篇工作提出了一套名为“Th…

作者头像 李华
网站建设 2026/8/2 6:41:14

5-数据库-SQL注入-报错注入-day13

MySQL 报错注入 — 原理与注入流程 ⚠️ 免责声明&#xff1a;本文旨在教学网络安全知识&#xff0c;帮助开发者理解SQL注入漏洞原理及防御方法。所有技术内容仅用于授权测试和安全研究&#xff0c;严禁用于任何非法攻击或未经授权的渗透测试。读者应遵守法律法规&#xff0c;因…

作者头像 李华
网站建设 2026/8/2 6:40:15

电工证学习笔记(三)

电工证 一、触电安全核心考点 人体触电电流参考值&#xff08;均为统计平均值&#xff0c;个体存在差异&#xff09; 50mA&#xff1a;公认致命电流&#xff1b;30mA&#xff1a;容易引发心室颤动、心肺功能停止&#xff1b; 部分人群耐受度高&#xff0c;部分人群低于30mA即出…

作者头像 李华
网站建设 2026/8/2 6:39:20

麻将AI开发实战:从规则引擎到强化学习的避坑指南

1. 项目概述&#xff1a;当AI牌手遇上麻将桌 麻将&#xff0c;这项风靡全球的策略游戏&#xff0c;如今正迎来一位全新的“牌友”——MahjongAI。作为一名长期混迹于AI与游戏交叉领域的开发者&#xff0c;我亲眼见证了从简单的规则引擎到如今能进行复杂策略博弈的AI牌手的进化…

作者头像 李华