> 文档中心 > React.forwardRef与useImperativeHandle的使用

React.forwardRef与useImperativeHandle的使用

1、React.forwardRef 会创建一个React组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。这种技术并不常见,但在以下两种场景中特别有用:

  • 转发 refs 到 DOM 组件
  • 在高阶组件中转发 refs

React.forwardRef 接受一个渲染函数(可理解为一个组件)作为参数。这个函数的参数是props和ref,返回 React 节点。

const FancyButton = React.forwardRef((props, ref) => (  <button ref={ref} className="FancyButton">    {props.children}  </button>));// You can now get a ref directly to the DOM button:const ref = React.createRef();<FancyButton ref={ref}>Click me!</FancyButton>;

在上述的示例中,React 会将 元素的 ref 作为第二个参数传递给 React.forwardRef 函数中的渲染函数。该渲染函数会将 ref 传递给 元素。
即:FancyButton中的ref传给forwardRef中的ref参数,进而再传给button的ref。

因此,当 React 附加了 ref 属性之后,ref.current 将直接指向 DOM 元素实例。

2、useImperativeHandle:可将ref的实例传递给父组件。

在大多数情况下,应当避免使用 ref 这样的命令式代码。

useImperativeHandle(ref,createHandle,[deps])

useImperativeHandle 应当与 forwardRef 一起使用,自定义组件FancyInput,如下:
子组件:

import React, { useRef, useState, useImperativeHandle } from 'react';function FancyInput(props, ref) {  const inputRef = useRef();  useImperativeHandle(ref, () => ({    focus: () => {      inputRef.current.focus();    }  }));  return <input ref={inputRef} ... />;}// 等同于 const FancyInput=React.forwardRef((props,ref){...})FancyInput = forwardRef(FancyInput);

这样写之后,渲染 FancyInput 的父组件就可以直接调用 inputRef.current.focus()。
父组件:

const fanRef= React.useRef();function handleClick(){// 在这里调用子组件的实例方法。fanRef.current.focus();}<FatherCompoent><FancyInput ref={fanRef}/><button onClick={handleClick}> Focus the input     </button></FatherCompoent>

本文主要参考React中文网,根据自己的理解加以总结。

React.forwardRef与useImperativeHandle的使用 超强干货来袭 React.forwardRef与useImperativeHandle的使用 云风专访:近40年码龄,通宵达旦的技术人生清水丽人化妆品