React hooks useImperativeHandle

1.前言

相比大家看到useImperativeHandle会感到十分陌生,但部分开源代码经常会出现它的身影、接下来我把我理解的内容写下来,有不对的地方欢迎友友们指出.

2.useImperativeHandle定义

React官网的定义

  • useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用
  • 用了ref的桥梁就可以在父组件中控制子组件了,而不仅仅只是子随父渲染了

个人理解

  • useImperativeHandle的作用是将子组件的指定元素暴漏给父组件使用。也就是父组件可以访问到子组件内部的特定元素。

3.获取元素的几种方式

  • 3.1 useRef:获取组件内部元素

    import {useRef} from "react"
    export default function() {
      //1. 获取组件内部元素
      const ele = useRef()
      //2. 获取组件内部元素
      const getElememnt = () => {
        console.log(ele.current)
      }
      return <div >
        <button onClick={()=>getElememnt()}>获取元素</button>
      //3. 获取组件内部元素
        <p ref={ref}></p>
      </div>
    }
    

    点击按钮,我们可以获取到p元素。上面是useRef获取元素的方法

    • 引入useRef,定义变量
    • 在需要获取的dom元素上使用ref进行变量绑定
    • 使用变量.current获取对应元素
  • 3.2 forwardRef

    • 父组件获取子组件内部的一个元素
      上面的useRef在函数组件可以获取自身组件内部的元素,但是如果我们需要在父组件获取或者操作儿子组件的一个元素,这时就会用到forwardRef

      //父组件
      import {useRef} from "react"
      import Son from "./son"
      export default function(){
        const ele = useRef()
        const getElement = () => {
          console.log(ele.current)
        }
        return <div>
          <button onClick={()=>getElement()}>点击获取子组件的元素</button>
          <Son ref={ele}/></div>
      }
      
      //son.js
      import {forwardRef} from "react"
      
      export default forwardRef(function(props,ref){
        return <div >
          <p ref={ref}></p>
        </div>
      })
      
      1. 父元素点击按钮后,可以获取到儿子组件的p元素。

      2. forwardRef在父组件获取儿子组件内部一个元素时,操作如下。

      3. 父组件按照useRef的规则绑定到儿子组件上

      4. 儿子组件使用forwardRef包裹,并在函数组件传递的参数接收,第一个参数porps接收父组件传递的数据,第二个ref接收的就是dom引用

      5. 在需要获取儿子组件的元素上直接绑定ref的值

  • 3.3 useImperativeHandle

    • 父组件可以获取/操作儿子组件多个元素

    • 它可以在父组件内部直接获取儿子组件任意的dom元素对象。

      //父组件
      import {useRef} from "react"
      import Son from "./son"
      export default function(){
        const ele = useRef()
        const getElement = () => {
          console.log(ele.current.ele1.current)
          console.log(ele.current.ele2.current)
        }
        return <div>
          <button onClick={()=>getElement()}>点击获取子组件元素</button>
          <Son ref={ele}/></div>
      }
      
      //son.js
      import {useRef,forwardRef,useImperativeHandle} from "react"
      export default forwardRef(function(props,ref){
        const ele1 = useRef()
        const ele2 = useRef()
        
        useImperativeHandle(ref,()=>{
          return {ele1,ele2}
        },[])
      
        return <div >
          <h2 ref={ele1}></h2>
          <h3 ref={ele2}></h3>
        </div>
      })
      
      结果
      <h2></h2>
      <h3></h3>
      
    • 父组件点击按钮后,可以一次性获取到多个标签元素,通过useImperativeHandle函数内部返回的对象可以获取对应的标签。列举下useImperativeHandle的参数

      useImperativeHandle(ref,()=>{
          return {dom1,dom2}
      },[])
      
    • 第一个参数是组件的第二个参数ref

    • 第二个参数是一个回调函数,内部返回的对象就是抛给父组件的元素对象

    • 第三个参数是一个依赖数组,类似useEffect的依赖数组,如果依赖数组内部传递的数据发生改变,就会重新触发回调函数

你可能感兴趣的:(react.js,javascript,前端)