react 的 refs 原理及应用 详细介绍

refs 的在哪?

  • refs 是你在创建类组件的时候从 React.component 中继承而来的
    react 的 refs 原理及应用 详细介绍_第1张图片

refs 使用说明

  • 在 vue 中也有 refs 的概念
  • 其实就是把 model(vdom) 层当中的东西渲染到我们的 view(dom) 层时
  • refs 引用的就是真实的 dom

refs 在什么场景操作真实 dom?

我在市面上看到了一些操作动画库的第三方库或者一些操作其他场景时我需要操作真实 dom 的时候,需要把这些业务交给第三方库的时候,我们才回去使用 ref 去引用这些 dom

有些像我们在原生的时候,给它一个 id 我们就可以 getElementById 获取元素,所以我们给它一个 ref 就可以通过 refs 这个属性去引用到 ref ,拿到的就是 dom 元素,就可以做一些只有真实 dom 才能操作的业务,这就是 ref 的一个使用场景

refs 介绍

需要抓取dom元素与第三方 DOM 库集成

  • 触发命令式动画
  • 管理焦点
  • 文本选择或媒体播放
  • dom 只能在浏览器 Navigator 才可能出现 dom 这个概念,才能够进行上述操作(比如在浏览器里面才有焦点,我们不可能在虚拟 dom 下进行操作,虚拟 dom 只是在管理我们被虚拟之后的一个 documnet)
  • ref 就是给我们操作真实 dom 提供了一个入口

refs 用法

//1. 通过字符串去引用,跟 vue 时一模一样的
<jsx元素 ref="名字"...
this.refs.名字
//2. 实例化
this.firstRef = React.createRef() //发生在构造器
<jsx ref={
     this.firstRef} />
  
this.firstRef 访问 -{
     current:dom}
//3. callback refs  回调  (其实还有第四个转发,较复杂,这里未列出)
<jsx ref={
     el => this.定义一个实例属性 = el}
this.定义一个实例属性  //后期用作访问jsx元素
  • 当组件挂载时,将 DOM el元素传递给 ref 的回调
  • 当组件卸载时,则会传递 null。
  • ref 回调会在 componentDidMount 和 componentDidUpdate 生命周期之前调用
vue 通过指令去操作真实 dom ,react 中就是用 ref 去引,引完以后你想使用 原生还是 第三方的库 随意

refs 用法(一)

//1. 通过字符串去引用,跟 vue 时一模一样的
<jsx元素 ref="名字"...
this.refs.名字
  • 他是一个 jsx 元素,所以它可能时 虚拟 dom 里面的内容,那迟早有一天 它会渲染到真实 dom 里面去,到那个时候我通过访问 ref =“名字” 的这个名字就能抓取到渲染以后的真实 dom 元素
  • 也就是当 jsx 转换成真实dom 的时候我可以访问这个元素,而不是 jsx
  • 我们可在组件里面通过 this 抓取组件,再通过 refs 来拿到实例身上的 refs 属性,在这里面就会有你的 起的名字
  • this.refs.名字 这个用法可能过时了,以后可能会被废弃
import React from 'react';
import ReactDom from 'react-dom'

class App extends React.Component {
     

  constructor(props){
     
    super(props);
  }

  render(){
     
    return (
      <div>
        <div ref="b2">box2</div>

        <button onClick={
     ()=>{
        //当我们点击的时候操作 dom 元素
          console.log(this);     //打印当前实例
          this.refs.b1.style.background='red';//dom操作
        }}>操作dom</button>

      </div>
    )
  }
}

ReactDom.render(
  <App />,
  document.getElementById('root')
);
  • 当我们点击按钮的时候进行操作真实 dom
    当我们点击以后效果图:
    react 的 refs 原理及应用 详细介绍_第2张图片
    react 的 refs 原理及应用 详细介绍_第3张图片

其实虚拟 dom 总归是要操作 真实 dom 的,所以不去操作真实dom 本身是一个不现实的做法,只能说尽量少操作

refs 用法(二)

//2. 实例化
this.firstRef = React.createRef() //发生在构造器
<jsx ref={
     this.firstRef} />
  
this.firstRef 访问 -{
     current:dom}
  • 你得实例化
  • react 上是有有一个方法叫做 createRef()
  • createRef() 是一个空的实例,触发的时间是越早越好

import React from 'react';
import ReactDom from 'react-dom'

class App extends React.Component {
     

  constructor(props){
     
    super(props);

    this.b3 = React.createRef();//空 ref元素  {current:null}

  }

  render(){
     
    return (
      <div>
        //
box3
绑定元素
<div>box4</div> <button onClick={ ()=>{ // console.log(this.b3.current) this.b3.current.style.background='red'; }}>操作dom</button> </div> ) } } ReactDom.render( <App />, document.getElementById('root') );

当我们点击后控制台打印当前实例:

react 的 refs 原理及应用 详细介绍_第4张图片

  • 可以看到 ref 里面只有 之前的 b1,b2
  • b3 实际上来自于你现在身上实例上的一个实例属性
  • 这个实例属性它是一个对象,目前他的对象 current 是一个空,因为没有做任何的引用
  • 这个 current 空对象代表实例化之后的空 ref 元素
  • 它就一个键值对,未来你可以添加多个键值对

  • 只有通过上文代码中的绑定元素才能使用 < div ref={this.b3}>box3
  • 当我们再次打印 console.log(this.b3.current) 就能得到当前元素
    在这里插入图片描述

refs 用法(三)

  • 他其实就是把 第一种方法和第二种方法合起来了(建议使用)
//3. callback refs  回调  (其实还有第四个转发,较复杂,这里未列出)
<jsx ref={
     el => this.定义一个实例属性 = el}
this.定义一个实例属性  //后期用作访问jsx元素
  • el 代表编译后的 jsx 元素,是一个 dom
  • 通过this 定义一个实例属性,这个实例属性 跟 this.b3 = React.createRef() 实例属性是一样的
  • 给这个实例属性实时的动态赋值为 el
知识补充:
这个 el 为什么是 jsx 元素?(底层原理)

ref 在内部定义的时候是可以接受 字符串和函数的,那如果你给这个 ref 再传递一个函数,
它在需要的时候就会去调这个回调函数,调一个回调函数 当然是可以给这个回调函数传一个参数,
所以它才被称之为 回调 ref 嘛。

在虚拟 dom 中,它对这个 jsx 放在 虚拟dom 中一定是有一个节点,比如是一个 div,
实际上每一个 虚拟 dom 都有一个key,你不给它的话它也会拿数组的下标做key
如果你给它key 的话他会有一个具体的key,如果没有给它 key 的话它会那我们的
这个枚举的这些里面有一个属性叫做 currens 做key,做个 key 之后,如果你在邦的时候
这个 jsx 元素给它指定了一个 ref ,那么 它的 props 里面就一定会有一个 ref 这样的属性,
这个 ref 属性里面就可以接受一个函数,当我们这样去邦的时候它就会去调这个函数,顺便
把这个 type 类型叫 div 的元素传给这个函数,所以它就拿到了这个所谓的 jsx 元素
  • 这一行就可以完成 ref 元素的引用,同时也能生成一个实例属性,通过实例属性来访问引用之后的 dom 元素
import React from 'react';
import ReactDom from 'react-dom'

class App extends React.Component {
     

  constructor(props){
     
    super(props);
  }

  render(){
     
    return (
      <div>
        <div ref={
     el=>this.b5=el}>box5</div>  ⬅⬅⬅⬅⬅
        <div>box6</div>

        <button onClick={
     ()=>{
     
          // console.log(this)
          this.b5.style.background='red';
        }}>操作dom</button>


      </div>
    )
  }
}

ReactDom.render(
  <App />,
  document.getElementById('root')
);

结果展示:
在这里插入图片描述

  • 可以看到是直接绑定在 这个实例属性身上的
  • 而且是一个 纯 dom 属性,可以直接访问,不需要再 current
  • 如果你只需要 纯 dom 这种方法比较简洁
    react 的 refs 原理及应用 详细介绍_第5张图片

你可能感兴趣的:(react,react)