使用 React.forwardRef 与自定义 ref prop 的值

2022-08-30 05:22:16

我看到这似乎是从 react 文档中将 ref 传递给子函数组件的受制裁方式:React.forwardRef

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>;

但是,与简单地传递自定义道具相比,这样做有什么好处呢?

const FancyButton = ({ innerRef }) => (
  <button ref={innerRef} className="FancyButton">
    {props.children}
  </button>
));

const ref = React.createRef();
<FancyButton innerRef={ref}>Click me!</FancyButton>;

我能想到的唯一优势可能是为refs提供一致的api,但是还有其他优势吗?传递自定义 prop 是否会在渲染时影响差异并导致其他渲染,因为 ref 在字段中存储为可变状态,这肯定不会影响差异?current

例如,假设你想传递多个引用(tbh,可能表示代码有异味,但仍然如此),那么我能看到的唯一解决方案是使用customRef props。

我想我的问题是使用自定义道具的价值是什么?forwardRef


答案 1

甚至 React 文档也提到自定义 ref prop 是一种更灵活的方法:forwardRef

如果你使用 React 16.2 或更低版本,或者如果你需要比 ref forwarding 提供的更大的灵活性,你可以使用这种替代方法,并显式传递一个 ref 作为不同名称的 prop

还有一个要点,丹·阿布拉莫夫(Dan Abramov)在其中写道:它的优势:

  • 与所有 React 版本兼容
  • 适用于类和函数组件
  • 简化了将 ref 传递到多层深的嵌套组件的过程

我想补充一点,像往常一样传递引用不会引起重大更改,并且是多个引用的方法。在我看来,唯一的好处是:forwardRef

  • DOM 节点、函数和类组件的统一访问 API(您提到过)
  • ref属性不会膨胀你的 props API,例如,如果你使用 TypeScript 提供类型

传递自定义 prop 是否会在渲染时影响差异并导致其他渲染?

如果将内联回调 ref 函数作为 prop 向下传递,则 ref 可能会触发重新呈现。但是,无论如何,将其定义为类实例方法或通过一些诸如.useCallback


答案 2

Ref是组件中的标准属性。React

某些包装其他组件以提供其他功能的组件用于引用包装的组件,并期望该组件具有属性。refref

组件最好具有与其他组件和库兼容的属性。ref

函数组件不能具有“ref”属性,而必须改用以提供属性。forwardRefref