17.React获取DOM的方式

3. 获取DOM方式refs

3.1. 如何使用Ref
    1. 在React的开发模式中,通常情况下不需要、也不建议直接操作原生DOM,但是某些特殊的情况,确实需要获取到DOM进行某些操作;
    • 1.1. 管理焦点,文本选择或媒体播放;
    • 1.2. 触发强制动画;
    • 1.3. 集成第三方DOM库;
    • 1.4. 我们可以通过refs获取DOM;
    1. 如何创建refs来获取对应的DOM呢?目前有三种方式:
    • 2.1. 方式一: 在React元素上绑定一个ref字符串(这种方式获取ref元素会被废弃,不推荐使用)

    • 2.2. 方式二: 提前创建好ref对象createRef(), 将创建出来的对戏那个绑定到元素上(推荐使用这种方式)

    • 2.3. 方式三: 传入一个回调函数,在对应的元素被渲染之后,回调函数被执行,并且将元素传入

    • 2.4. 示例代码如下:

      js 复制代码
        import React, { PureComponent, createRef } from 'react'
      
        export class App extends PureComponent {
          constructor() {
            super()
            this.state = {
        
            }
            // 1. 创建的ref不涉及页面更新的东西,不涉及到渲染的东西
            this.titleRef = createRef()
            this.titleEl = null
      
      
          }
          getNativeDom () {
            // 不建议这样拿原生dom
            // const h2El = document.querySelector('h2')
      
            // 1. 方式一: 在React元素上绑定一个ref字符串(这种方式获取ref元素会被废弃,不推荐使用)
            // console.log(this.refs.why)
            // 2. 方式二: 提前创建好ref对象,createRef(), 将创建出来的对戏那个绑定到元素上(推荐使用这种方式)
            // console.log(this.titleRef.current)
            // 3. 方式三: 传入一个回调函数,在对应的元素被渲染之后,回调函数被执行,并且将元素传入
            console.log(this.titleEl)
          }
          render() {
            return (
              <div>
                <h2 ref='why'>Hello World</h2>
                <div ref={this.titleRef}>你好啊,李银河</div>
                {/* 传入一个函数,当元素渲染出来之后自动回调这个函数,回调函数时并把元素作为参数传递给这个函数 */}
                <div ref={el => this.titleEl = el }>你好啊,世界</div>
                <button onClick={(e) => this.getNativeDom()}>获取ref元素</button>
              </div>
            )
          }
        }
      
        export default App
3.2. ref获取类组件实例
    1. 类组件的ref获取方式和绑定元素类似,通过ref属性绑定组件实例
    1. 示例代码如下:
    jsx 复制代码
      import React, { PureComponent, createRef } from 'react'
    
      export class HelloWorld extends PureComponent {
        test () {
          console.log('------')
        }
        render() {
          return (
            <div>
              <h2>Hello World!</h2>
            </div>
          )
        }
      }
    
    
      export class App extends PureComponent {
        constructor() {
          super()
          this.state = {
      
          }
          // 1. 创建的ref不涉及页面更新的东西,不涉及到渲染的东西
          this.hwRef = createRef()
        }
        getComponent () {
          console.log(this.hwRef.current)
          this.hwRef.current.test()
        }
        render() {
          return (
            <div>
              <HelloWorld ref={this.hwRef} />
              <button onClick={(e) => this.getComponent()}>获取组件实例</button>
            </div>
          )
        }
      }
    
      export default App
3.3. ref获取函数组件(ref的转发)
    1. 在前面我们学习ref时讲过,ref不能应用于函数式组件;
    • 1.1. 因为函数式组件没有实例,所以不能获取对应的组件对象
    1. 但是,在开发中我们可能想要获取函数式组件中某个元素的DOM,这个时候我们应该如何操作呢?
    • 方式一: 直接传入ref属性(错误的做法)
    • 方式二: 通过forwardRef()高阶函数
    1. 示例代码如下:
    jsx 复制代码
      import React, { PureComponent, createRef, forwardRef } from 'react'
    
      const HelloWorld = forwardRef (function (props, ref) {
        // 1. 在前面学习的ref,ref不能应用于函数式组件
        //  - 1.1. 函数式组件没有实例,所以不能获取对应的组件对象;
        // 2. 通过forwardRef高阶函数;
        return (
          <div>
            <h2  ref={ref}>Hello World!</h2>
            <p>哈哈哈</p>
          </div>
        )
      })
    
    
      export class App extends PureComponent {
        constructor() {
          super()
          this.state = {
      
          }
          // 1. 创建的ref不涉及页面更新的东西,不涉及到渲染的东西
          this.hwRef = createRef()
        }
        getComponent () {
          console.log(this.hwRef.current)
        }
        render() {
          return (
            <div>
              <HelloWorld ref={this.hwRef} />
              <button onClick={(e) => this.getComponent()}>获取函数组件实例</button>
            </div>
          )
        }
      }
    
      export default App
3.4. ref的类型
    1. ref的值根据节点的类型而有所不同
    • 1.1. 当ref属性用于HTML元素时,构造函数中使用React.createRef()创建的ref接受底层DOM元素作为其current属性
    • 1.2. 当ref属性用于自定义class组件时,ref对象接收组件的实例作为其current属性
    • 1.3. 不能在函数组件上使用ref属性,因为他们没有实例
    1. 函数组件是没有实例的,所以无法通过ref获取他们的实例:
    • 2.1. 但是某些时候,我们可能想要获取函数式组件中的某个DOM元素;
    • 2.2. 这个时候我们可以通过React.forwardRef(), 当ref属性用于通过forwardRef转发的函数式组件时,ref对象接收组件内部转发的具体元素或组件实例作为其current属性。
    • 2.3. 后面还会记录到hooks中如何使用ref;
相关推荐
excel2 小时前
Vue 编译核心中的运行时辅助函数注册机制详解
前端
excel2 小时前
🌿 深度解析 Vue DOM 编译器模块源码:compile 与 parse 的构建逻辑
前端
excel2 小时前
深度解析 Vue 编译器中的 transformShow:v-show 指令的编译原理
前端
excel2 小时前
深度解析:decodeHtmlBrowser —— 浏览器端 HTML 解码函数设计
前端
excel2 小时前
深度解析:Vue 模板编译器中的 transformVText 实现原理
前端
excel2 小时前
深度解析:isValidHTMLNesting —— HTML 嵌套合法性验证的设计与实现
前端
冴羽2 小时前
看了下昨日泄露的苹果 App Store 源码……
前端·javascript·svelte
excel2 小时前
深入解析 Vue 3 编译器中的 transformOn:事件指令的编译机制
前端
excel2 小时前
Vue DOM 编译错误系统解析:DOMErrorCodes 与 createDOMCompilerError
前端