为什么,确切地说,我们需要 React.forwardRef? [英] Why, exactly, do we need React.forwardRef?

查看:113
本文介绍了为什么,确切地说,我们需要 React.forwardRef?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

const MyComponent = (props) =>{返回 }

我希望能够做到

...myRef.scrollTo({x: 0});

所以我需要一种方法将引用转发到 .让我们尝试将 ref 放在 props 上:

const MyComponent = (props) =>{返回 <ScrollView ref={props.scrollRef} .../>}...<MyComponent scrollRef={myRef}/>...myRef.scrollTo({x: 0});

我刚刚在 iOS 上使用 React Native 尝试过,它确实有效.我看到了几个优于 React.forwardRef 的优点:

  • 更简单,因为我不需要使用其他 React API.
  • 如果有多个孩子需要参考转发,也可以使用.
  • 在我看来,这种方法是

React.forwardRef 的优势是什么?为什么在 React 16.3 中添加它?

解决方案

注意,使用另一个命名的 prop 没有区别,比如 innerRef FORWARDING,它会起作用一样.


重构类组件

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

//使用 forwardRef 将类组件 API 重构为功能组件<组件引用={myRef}/>

React.forwardRef 将是您唯一的选择(进一步详细解释).

清理 API

作为图书馆作者,您可能想要一个用于ref转发的可预测 API.

例如,如果您实现了一个 Component 并且有人想给它附加一个引用,他有两个选项,具体取决于您的 API:

<组件innerRef={myRef}/>

  • 开发者需要知道有一个用于转发的自定义道具
  • innerRef 附加到哪个元素?我们不知道,应该在API中提到还是我们console.log(myRef.current)

<组件引用={myRef}/>

  • 默认行为类似于 HTML 元素上使用的 ref 属性,通常附加到内部包装器组件.

注意 React.forwardRef

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

<块引用>

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

Let's say I have a component with a scrollable subcomponent, and I want to expose the ability to scroll:

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

I want to be able to do

<MyComponent ref={myRef} />

...

myRef.scrollTo({x: 0});

So I need a way to forward the ref to the <ScrollView>. Let's try putting the ref on the props:

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

...

<MyComponent scrollRef={myRef} />

...

myRef.scrollTo({x: 0});

I just tried that with React Native on iOS, and it indeed works. I see several advantages over React.forwardRef:

  • Simpler, because I don't need to use another React API.
  • Works also if there is more than one child who needs ref forwarding.
  • Seems to me that this approach is

What's the advantage of React.forwardRef? Why was it added in React 16.3?

解决方案

Note that there is no difference between using another named prop like innerRef FOR FORWARDING, it will work the same.


Refactoring class components

Since React moved toward function components (hooks) you might want to refactor the class component code to a function component without breaking the API.

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

React.forwardRef will be your only option (further explained in details).

Clean API

As a library author you may want a predictable API for ref forwarding.

For example, if you implemented a Component and someone wants to attach a ref to it, he has two options depending on your API:

<Component innerRef={myRef} />

  • The developer needs to be aware there is a custom prop for forwarding
  • To which element the innerRef attached? We can't know, should be mentioned in the API or we console.log(myRef.current)

<Component ref={myRef} />

  • Default behavior similar to ref prop used on HTML elements, commonly attached to the inner wrapper component.

Notice that React.forwardRef can be used for function component and HOC (for class component see alternative below).

Ref forwarding is not limited to DOM components. You can forward refs to class component instances, too.

For function components, forwardRef sometimes comes with useImperativeHandle combo (in class component you just call the class methods on ref instance: 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.
});


Important behavior of ref prop without forwardRef.

For the class component, this code alone will attach the ref to CLASS INSTANCE which is not useful by itself and need another ref for forwarding:

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

Full example, check the logs:

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

In function components, it won't even work because functions don't have instances.

By default, you may not use the ref attribute on function components because they don’t have instances. [1]

这篇关于为什么,确切地说,我们需要 React.forwardRef?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆