到底为什么我们需要 React.forwardRef?

问题描述 投票:0回答:1

假设我有一个带有可滚动子组件的组件,并且我想公开滚动的功能:

const MyComponent = (props) => {
    return <ScrollView ... />
}

我希望能够做到

<MyComponent ref={myRef} />

...

myRef.scrollTo({x: 0});

所以我需要一种方法将参考转发到

<ScrollView>
。让我们尝试将参考放在道具上:

const MyComponent = (props) => {
    return <ScrollView ref={props.scrollRef} ... />
}

...

<MyComponent scrollRef={myRef} />

...

myRef.scrollTo({x: 0});

我刚刚在 iOS 上使用 React Native 进行了尝试,它确实有效。我看到了

React.forwardRef
的几个优点:

  • 更简单,因为我不需要使用另一个 React API。
  • 如果有多个孩子需要转发参考,也可以使用。

React.forwardRef
有什么好处?为什么在 React 16.3 中添加它?

reactjs react-native
1个回答
46
投票

请注意,使用其他命名道具(例如

innerRef
FOR FORWARDING)没有区别,它的工作原理是相同的。


重构类组件

自从 React 转向函数组件(钩子),您可能希望将类组件代码重构为函数组件而不破坏 API

// Refactor class component API to function component using forwardRef
<Component ref={myRef} />

React.forwardRef
将是您唯一的选择(详细说明)。

干净的API

作为库作者,您可能需要一个可预测 API 来进行

ref
转发。

例如,如果您实现了

Component
并且 有人想要为其附加引用,他有两个选项,具体取决于您的 API:

<Component innerRef={myRef} />
  • 开发者需要知道有一个用于转发的自定义道具
  • innerRef
    连接到哪个元素?我们不知道,应该在 API 中提及或者我们
    console.log(myRef.current)

<Component ref={myRef} />
  • 默认行为类似于 HTML 元素上使用的
    ref
    prop,通常附加到内部包装组件。

请注意,

React.forwardRef
可用于函数组件和 HOC(对于类组件请参阅下面的替代方案)。

引用转发不限于 DOM 组件。您也可以将引用转发到类组件实例。

对于函数组件,

forwardRef
有时带有
useImperativeHandle
组合(在类组件中,您只需调用引用实例上的类方法:
ref.current.myAttr()

// Same usage
<Component ref={myRef} />

const Component = React.forwardRef((props, ref) => {
  // you can forward ref <div ref={ref} />
  // you can add custom attributes to ref instance with `useImperativeHandle`
  // like having ref.myAttribute() in addition to ones attached to other component.
});

没有

refforwardRef 道具的

重要行为

对于类组件,仅此代码会将引用附加到 CLASS INSTANCE,这本身没有用,需要另一个引用来转发:

// usage, passing a ref instance myRef to class Component
<Component ref={myRef} />

完整示例,检查日志:

// We want to forward ref to inner div
class ClassComponent extends React.Component {
  innerRef = React.createRef();
  render() {
    // Notice that you can't just `this.props.ref.current = node`
    // You don't have `ref` prop, it always `undefined`.
    return <div ref={this.innerRef}>Hello</div>;
  }
}

const Component = () => {
  const ref = React.useRef();

  useEffect(() => {
    // The ref attached to class instance
    console.log(ref.current);
    // Access inner div through another ref
    console.log(ref.current.innerRef);
  }, []);

  return <ClassComponent ref={ref} />;
};

Edit React Template (forked)

在函数组件中,它甚至不起作用,因为函数没有实例。

默认情况下,您不能在函数组件上使用 ref 属性,因为它们没有实例。 [1]

© www.soinside.com 2019 - 2024. All rights reserved.