第34节——useImperativeHandle

一、概念

useImperativeHandle可以让父组件获取并执行子组件内某些自定义函数(方法)。本质上其实是子组件将自己内部的函数(方法)通过useImperativeHandle添加到父组件中useRef定义的对象中。

注意:
1、useRef创建引用变量
2、React.forwardRef将引用变量传递给子组件
3、useImperativeHandle将子组件内定义的函数作为属性,添加到父组件中的ref对象上。

因此,如果想使用useImperativeHandle,那么还要结合useRef、React.forwardRef一起使用。

二、React.forwardRef

React.forwardRef 会创建一个React组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。

这种技术并不常见,但在以下两种场景中特别有用:

(1)转发 refs 到 DOM 组件

(2)在高阶组件中转发 refs

React.forwardRef 接受渲染函数作为参数。React 将使用 props 和 ref 作为参数来调用此函数。此函数应返回 React 节点。

二、基本用法

useImperativeHandle(ref,create,[deps])函数前2个参数为必填项,第3个参数为可选项。
第1个参数为父组件定义的useRef的值;
第2个参数为子组件要附加给ref的对象,该对象中的属性即子组件想要暴露给父组件的函数(方法);
第3个参数为可选参数,为函数的依赖变量。凡是函数中使用到的数据变量都需要放入deps中,如果处理函数没有任何依赖变量,可以忽略第3个参数。

请注意:
1、这里面说的“勾住子组件内自定义函数”本质上是子组件将内部自定义的函数添加到父组件的ref.current上面。
2、父组件若想调用子组件暴露给自己的函数,可以通过 ref.current.xxx 来访问或执行

1、实际案例

父组件调用子组件里面的方法

父组件

import { useRef } from "react";
import C from "./c";


export default () => {
  const childRef = useRef();


  const childAdd = () => {
    //父组件调用子组件内部 add函数
    childRef.current.add();
  };


  return (
    
父组件
{/* 父组件通过给子组件添加 ref 属性,将childRef传递给子组件, 子组件获得该引用即可将内部函数添加到childRef中 */}
); };

子组件

import React, { useImperativeHandle } from 'react'
import { useState } from 'react'

/**
 * 就可以接收到父组件传过来的ref
 */
export default React.forwardRef((props, ref) => {

  const [num, setNum] = useState(1)

  const add = () => {
    console.log("我是A组件里面的方法")
    setNum(num + 1)
  }

  /**
   * 第一个参数是ref,父组件传过来的
   * 我们想要把方法挂载的ref
   * 
   * 第二个参数是一个方法,必须有返回值
   * 返回的值就是要挂再到useRef上面的值
   * 
   * 第三个参数是依赖项 依赖项改变的情况第一个参数
   * 会重新调用,如果依赖项不传则每次render都会调用
   */
  useImperativeHandle(ref, () => {
    return {
      add
    }

    /**
     * 如果依赖项传一个空数组
     * 则第一个方法只会在初始化的时候调用一次
     * 里面的值不是最新的
     */
  }, [num])


  return (
    
哈哈 我是A组件要使用imperative--{num}
) })

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