iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >如何深入理解React的ref 属性
  • 500
分享到

如何深入理解React的ref 属性

2024-04-02 19:04:59 500人浏览 八月长安
摘要

目录概述1. Refs 对象的创建1.1 React.createRef()1.2 React.useRef(initialValue)2. ref 属性的使用2.1 为原生DOM元

概述

首先,Refs 和 ref 是两个概念,Refs 是 React 提供的可用特定 api 创建的一个对象。该对象的结构如下:

这个对象只有一个属性就是 current ,那么这个对象是用来干嘛的呢?

Refs 允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。(DOM节点就是指原生DOM元素,在render()方法中创建的 React 元素就是指 React 的类组件元素)

我们可以想象这样一个需求,两个兄弟元素,一个是 div ,一个是 button。现在想实现点击 button,改变 div 的背景颜色。在原生的 DOM 技术中,我们可以在 button 的点击函数里使用 document.querySelector('xxx') 的方式选中 div 节点,然后改变其背景样式。但是无论是在 Vue 还是 React 这样的框架中,页面元素都是动态生成的,无法使用 DOM API 获取的方式。而且 React 中大部分操作的元素不是 原生DOM元素,而是 React 元素。 那么如何选择到某一个 原生DOM元素 或者 React 元素呢?

其实,理论上,我们不需要进行任何的选择操作,这样会失去前端框架中组件独立的概念。一般情况下是通过 组件通信 的方式进行事件的处理的。上述的情况可以使用 EventBus 的方式进行组件通信,button 的点击事件中进行自定义事件的触发,在 div 中进行自定义事件的监听,让 button 以事件通知的方式告知 div 让其改变背景色,而不是在 button 的事件中直接获取 div 进行操作。

但是 React 为我们提供了直接访问 DOM元素 和 React 元素的方式,就是通过 Refs。使用的方式很简单,就是,为想要访问的元素上添加 ref 属性,将 Refs 对象附加到 ref 属性上,那么此时 Refs 对象的 current 属性就不再是空,而是对应的 DOM元素 或 React 元素实例了。

1. Refs 对象的创建

在 React 中,创建 Ref 对象的方式有两种:

1.1 React.createRef()

使用 React.createRef() 的方式可以创建一个 Ref 对象,可通过附加到 ref 属性上访问一个 原生DOM元素 或者 class 组件。
这种方式既可以在函数组件中使用,也可以在class组件中使用。

1.2 React.useRef(initialValue)

在 React 16.8 中新增了 Hook 后,又多了一个可以创建 Ref 对象的 Hook。即 React.useRef(initialValue)。
useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。
这种方式只能在函数组件中使用。

2. ref 属性的使用

ref 属性只能被添加到 原生DOM元素 或者 React的 class 组件上。不能在 函数组件 上使用 ref 属性,因为函数组件没有实例。

若想在函数组件上使用 ref 属性,可以通过 React.forwardRef 将 Ref 转发到函数组件内部的 原生 DOM 元素上。

2.1 为原生DOM元素添加 ref

class类组件内部


class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = React.createRef()
    } 
    componentDidMount(){
        console.log(this.myRef)
        console.log(this.myRef.current)
    }
    render(){
        return (
            <div ref={this.myRef}>我是App组件</div>
        )
    }
}

函数组件内部


const App = ()=>{
    const myRef = React.useRef(null)
    //const myRef = React.createRef() 两种创建 ref 对象的方式都可以
    React.useEffect(()=>{
        console.log(myRef)
        console.log(myRef.current)
    },[]) //模拟生命周期
    return (
        <div ref={myRef}>我是函数组件内部使用ref的div</div>
    )
}

2.2 为class组件添加 ref


class ClassChild extends React.Component{
    render(){
        return (
            <div>我是App组件的 class 子组件 ClassChild</div>
        )
    }
}

class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = React.createRef()
    } 
    componentDidMount(){
        console.log(this.myRef)
        console.log(this.myRef.current)
    }
    render(){
        return (
            <ClassChild ref={this.myRef}/>
        )
    }
}

2.3 为class组件转发的原生DOM元素添加 ref

ref 转发原理就是将父组件中定义的 ref 对象当作普通属性的方式传递给子组件,然后子组件通过 props 接收再赋值给自己 DOM元素 上。


class ClassChild extends React.Component{
    render(){
        return (
            <div ref={this.props.refProp}>我是App组件的 class 子组件 ClassChild</div> //添加了 ref
        )
    }
}

class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = React.createRef()
    } 
    componentDidMount(){
        console.log(this.myRef)
        console.log(this.myRef.current)
    }
    render(){
        return (
            <ClassChild refProp={this.myRef}/> //作为普通属性传递
        )
    }
}

2.4 为函数组件转发的原生DOM元素添加 ref

根据class类组件转发的原理,我想到的实现方法如下:


const FunChild = (props)=>{
    return (
        <div ref={props.refProp}>我是函数组件 FunChild</div>
    )
}
class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = React.createRef()
    } 
    componentDidMount(){
        console.log(this.myRef)
        console.log(this.myRef.current)
    }
    render(){
        return (
            <FunChild refProp={this.myRef}/>
        )
    }
}

这种实现方式是可以的,但这不是在 函数组件 上直接使用 ref 属性的方式,React 提供了在函数组件上直接使用 ref 的方式,就是使用 React.forwardRef 创建 React 元素。

React.forwardRef


const FunChild = React.forwardRef((props, ref)=>{
    return (
        <div ref={ref}>我是函数组件 FunChild</div>
    )
}) // 使用 React.forwardRef 改造函数组件
class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = React.createRef()
    } 
    componentDidMount(){
        console.log(this.myRef)
        console.log(this.myRef.current)
    }
    render(){
        return (
            <FunChild ref={this.myRef}/>  //直接给函数组件传递 ref
        )
    }
}

感觉 React.forwardRef 就是把 ref 属性单独从 props 中抽离出来了。
尽管上述方式实现了在函数组件上使用 ref 属性,但此时的 Ref 对象是访问的函数组件内部的 原生DOM元素 或其他 class组件。也就是说,在这里函数组件只是起到了一个转发的作用。

3. 回调 Refs

上述的方式中,我们都是通过创建一个 Ref 对象,通过 ref 属性的方式挂载到 原生DOM元素 或者 class 组件上用于访问该元素或实例。
实际上,ref 属性除了可以接收一个 Ref 对象外,还可以接收一个回调函数。
当 ref 属性接收 Ref 对象时,会将其对应的 DOM元素 或者 class组件实例 直接赋值给 Ref 对象中的 current 属性上。而当 ref 属性接收一个回调函数时,会将其对应的 DOM元素 或 class组件实例作为回调函数的参数调用回调函数。
因此我们可以通过回调 Refs 的方式不依靠 Ref 对象,更灵活地控制要访问的元素或实例。


class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = null
        this.setMyRef = (element)=>{
            this.myRef = element
        }
    } 
    componentDidMount(){
        console.log(this.myRef)
    }
    render(){
        return (
            <div ref={this.setMyRef}>我是App组件</div>
        )
    }
}

以上就是如何深入理解React的ref 属性的详细内容,更多关于深入理解React的ref 属性的资料请关注编程网其它相关文章!

--结束END--

本文标题: 如何深入理解React的ref 属性

本文链接: https://www.lsjlt.com/news/126052.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何深入理解React的ref 属性
    目录概述1. Refs 对象的创建1.1 React.createRef()1.2 React.useRef(initialValue)2. ref 属性的使用2.1 为原生DOM元...
    99+
    2024-04-02
  • 深入详解React中的ref
    对于 Ref 理解与使用,一些读者可能还停留在用 ref 获取真实 DOM 元素和获取类组件实例层面上其实 ref 除了这两项常用功能之外,还有很多别的小技巧通过本篇文章的学习,你将收获 React ref 的基本和进阶用法,并且能够明白 ...
    99+
    2023-05-14
    ref React
  • 深入理解React三大核心属性
    目录1、State属性2、Props 属性3、Refs 属性 (1)字符串形式(2)函数回调形式(3)createRef创建ref容器1、State 属...
    99+
    2024-04-02
  • 如何理解Vue中的ref属性
    这期内容当中小编将会给大家带来有关如何理解Vue中的ref属性,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。上述就是小编为大家分享的如何理解Vue中的ref属性了,如果刚好有类似的疑惑,不妨参照上述分析进...
    99+
    2023-06-25
  • React中ref属性的示例分析
    这篇文章主要介绍了React中ref属性的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。概述首先,Refs 和 ref 是两个概念,Refs 是 React 提供的可...
    99+
    2023-06-15
  • React中的ref属性的使用示例详解
    目录ref 简介1. 字符串形式的ref2. create形式的ref3. 回调函数形式的ref总结:ref 简介 React提供的这个ref属性,表示为对组件真正实例的引用,其实就...
    99+
    2023-05-17
    React ref属性使用 React ref属性
  • 深入理解CSS中position属性的常见属性值
    绝对定位的常用属性值解析:学习CSS中的position属性,需要具体代码示例CSS中的position属性可以用于控制元素在页面上的定位方式。其中,绝对定位是position属性值之一,主要用于将元素脱离文档流,并相对于最近的祖先元素进行...
    99+
    2023-12-28
    绝对定位 CSS学习 position属性
  • 深入理解springMVC中的Model和Session属性
    目录springMVC的范围spring的@MODELATTRIBUTEspring Model和Request后边的原因Spring的@SESSIONATTRIBUTE控制对话属性...
    99+
    2024-04-02
  • 深入理解React State 原理
    目录问题:setState 到底是同步还是异步的?类组件statesetState原理揭秘函数组件state问题:setState 到底是同步还是异步的? 如果对 React 底层有...
    99+
    2024-04-02
  • 怎样深入理解react
    这篇文章给大家介绍怎样深入理解react,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。理解ReactElement和ReactClass的概念首先让我们理解两个概念:ReactElem...
    99+
    2024-04-02
  • React深入了解原理
    目录VDOM(虚拟dom)Fiber架构初始化渲染更新时render阶段commit阶段VDOM(虚拟dom) react和vue都是基于vdom的前端框架。 web界面由DOM树来...
    99+
    2024-04-02
  • 深入理解CSS属性选择器的用法
    深入了解CSS选择器的属性选择器,需要具体代码示例 引言:CSS选择器是前端开发中常用的一种技术,用来选择符合特定条件的HTML元素,并为其添加样式或效果。而属性选择器是其中的一种类型,通过属性的值来选择元素,使得我们能够更精确...
    99+
    2024-01-15
    CSS选择器 深入了解 属性选择器
  • React的Ref如何限制
    本篇内容介绍了“React的Ref如何限制”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为什么是逃生舱?先思考一个问题:为什么ref、eff...
    99+
    2023-07-02
  • 深入了解CSS中display属性的常见属性值
    深入了解CSS中display属性的常见属性值,需要具体代码示例 引言: CSS的display属性是控制元素如何显示的重要属性之一。它决定了元素在文档中的呈现方式,包括是否生成盒子、是否独占一行、是否可见等。本文将深入介绍di...
    99+
    2024-02-02
    inline none
  • 深入理解React的自定义Hook
    自定义 Hooks 的核心是共享组件之间的逻辑。使用自定义 Hooks 能够减少重复的逻辑,更重要的是,自定义 Hooks 内部的代码描述了它们想做什么,而不是如何做。当你将逻辑提取到自定义Hooks 中时,你可以隐藏如何处理某些"...
    99+
    2023-05-14
    前端 代码规范 React.js
  • 深入理解React调度(Scheduler)原理
    目录异步调度时间分片异步调度原理总结异步调度 问题:由于对于大型的 React 应用,会存在一次更新,递归遍历大量的虚拟 DOM ,造成占用 js 线程,使得浏览器没有时间去做一些动...
    99+
    2024-04-02
  • 深入理解React Native核心原理(React Native的桥接(Bridge)
    在这篇文章之前我们假设你已经了解了React Native的基础知识,我们会重点关注当native和JavaScript进行信息交流时的内部运行原理。 主线程 在开始之前,我们需要知...
    99+
    2024-04-02
  • python类属性学习深入讲解
    class MyClass(): # 直接将属性定义在类中,这种属性称为 类属性 # 类属性可以通过实列对象和类对象访问,但是只能通过类对象修改 # 类属性都是用来保...
    99+
    2024-04-02
  • 从原生JavaScript到React深入理解
    目录从头开始理解 React原生 JavaScript 和 DOMReact 的基础咱老百姓也能学会的 JSX从头开始理解 React 作者:Stéphane B&ea...
    99+
    2024-04-02
  • react如何修改属性值
    这篇文章主要讲解了“react如何修改属性值”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“react如何修改属性值”吧!react修改属性值的方法:1、打开相应的代码文件;2、创建好数组对象...
    99+
    2023-07-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作