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

2023-12-11

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

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

我希望能够做到

<MyComponent ref={myRef} />

...

myRef.scrollTo({x: 0});

所以我需要一种方法将裁判转发给<ScrollView>。让我们尝试将 ref 放在 props 上:

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 中添加它?


请注意,使用另一个命名的 prop 没有什么区别,比如innerRef 转发,它的工作原理是一样的。


重构类组件

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

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

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

干净的API

作为图书馆作者,您may want a 可预测API 用于ref转发。

例如,如果您实施了Component and 有人想附加一个参考,根据你的 API,他有两个选项:

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

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

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

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

对于功能组件来说,forwardRef有时带有useImperativeHandle组合(在类组件中,您只需调用 ref 实例上的类方法: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.
});

重要行为 of ref支柱无forwardRef.

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

// 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]

  • 前向引用.
  • Refs 和 DOM.
  • 为什么我们需要ref转发?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

到底为什么我们需要 React.forwardRef ? 的相关文章

随机推荐

  • 如何在php中提取2个标签之间的文本

    我需要在一堆文本中找到 2 个标签 并保留它们之间的任何文本 例如 如果 开始 标签是 start 结束 标签是 end 鉴于此文本 rtyfbytgyuibg start isnv4b987b6vdc5y6ughnjmn9b8v76cty
  • 如何将动画图像插入仅适用于 Outlook 2013 的电子邮件正文? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我正在尝试将 gif 插入电子邮件正文中 并将其显示在 Outlook 中 我尝试过插入 图片 但它会将 gif 转换为静态图像形式 即使原始图像是动画的 如何在 Outlook 中
  • 如何在这段 PHP 和 MySQL 代码中演示 SQL 注入?

    首先我想指出 这是对我自己的数据库的一次教育尝试 目的是更好地理解 MySQL 注入以保护我自己的代码 我需要找出几个示例来说明如何根据以下代码构建 MySQL 注入 这是一个基本的用户登录系统 我接受用户名和密码而不进行任何转义 user
  • 有没有用 Java 实现的验证 HTML 解析器?

    我需要用 Java 解析 HTML 4 理想情况下 我想要一个与 SAX 兼容的实现 我知道 Java 有许多 HTML 解析器 但是 它们似乎都执行 整理 换句话说 它们将纠正格式错误的 HTML 我不想要这个 我的要求是 没有整理 如果
  • Flutter 键盘使文本字段隐藏

    我是新来的扑腾 我添加了一个带有文本字段的表单 当我单击文本字段并且键盘出现时 文本字段会上升 这是我的代码 Widget build BuildContext context MediaQueryData mediaQuery Media
  • 我想沿着特定路径制作对象的动画

    我必须移动路径上的小矩形 在画布内单击后 矩形会移动 我无法为其设置动画 因为对象只是跳转到所需的点 请在以下位置找到代码Fiddle HTML
  • InstallShield Basic MSI 卸载不显示带有“完成”按钮的对话框

    我使用 InstallShield 2018 并创建了一个 Basic MSI 项目 卸载产品时 它会确认我是否要继续卸载 确认后开始卸载 但随后它就消失了 最后没有显示一个对话框 您可以在其中单击 完成 按钮 因此 用户不知道卸载是否完成
  • 注册全局热键而不禁用其密钥

    我想制作一个程序 即使它在任何时候都不活动 也可以捕获键盘事件 Hooks 太复杂了 我需要做很多事情才能使其正常工作 制作 DLL 读取它等等 所以我决定继续使用热键 但现在我有一个问题 注册热键会禁用键盘上的按键 因此我只能将按键发送到
  • 为什么要使用指针? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我知道这是一个非常基本的问
  • 对大 O 表示法感到困惑

    根据这本书 大O的意思是 f n O g n means c g n is an upper bound on f n Thus there exists some constant c such that f n is always c
  • Windows Phone下如何获取设备方向改变事件

    对于 Windows Phone 当设备进入横向模式时 我是否可以注册一个事件 我之所以问这个问题是因为我们有一个带有输入框的视图 当处于横向模式时 TextBox部分被键盘阻挡 所以我想当页面处于横向模式时可能必须隐藏页面上的一些附加信息
  • Rails 中的 JQuery 在从另一个页面链接后失败,但在页面加载时工作

    我在主页上使用了一个报价旋转器 当我直接从浏览器加载页面 在浏览器中输入地址并按回车键 时 它工作正常 但是 如果我单击指向我网站中另一个页面的链接 然后链接回主页 它就会停止工作 更具体地说 引号开始重叠 几乎就像该方法的两个实例正在运行
  • ResolverStyle.STRICT 在“@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)”中不起作用

    我在用 DateTimeFormat iso DateTimeFormat ISO DATE JsonFormat pattern MM dd yyyy private LocalDate start 但它接受02 30 2019并转换为0
  • ado.net 使用“using”语句时关闭连接

    我正在像这样对 SQL Server 进行数据库访问方法 using SqlConnection con new SqlConnection connection string using SqlCommand cmd new SqlCom
  • 优化插入符的灵敏度似乎仍然可以优化 ROC

    我正在尝试使用插入符号来最大化我的模型选择的灵敏度rpart 为此 我尝试复制此处给出的方法 向下滚动到使用用户定义函数 FourStat 的示例 caret 的 github 页面 create own function so we ca
  • 如何创造漩涡/漩涡效果?

    我试图在作为传感器的圆形体上产生涡旋效果 我一直在寻找这个 我寻找的所有示例都是用 C 或 Objective C 编写的 但我似乎没有很好地翻译它们 当我的对象碰撞时 它调用 beginContact 并设置一个标志 以便我可以调用 bo
  • window.open(url, windowname, opts) 在新选项卡中打开,而不是在 Firefox 中打开新窗口

    似乎 尝试在jsfiddle window open http www google com window name width 400 height 320 完全停止在 Firefox 中打开新窗口 无论您输入什么内容作为 window
  • 针对客户和员工的 Spring Security 用户身份验证

    我是 Spring Security 的新手 我有一个带有两种不同类型实体的 Spring Boot 应用程序 客户和员工 在员工中 我有普通员工 管理员和超级用户 由于我使用的是 JPA 因此每个实体都有自己的repository 如何建
  • Oracle 数据访问组件 64 位无法在 IIS Express 7.5 中工作

    我已经安装了 ODAC Oracle 数据访问组件64 bit odp net 4 但不幸的是它不能与 IIs Express 一起使用 IIS Express文档说它支持32位和64位系统 它是否可以与 odp net 4 64 位 一起
  • 到底为什么我们需要 React.forwardRef ?

    假设我有一个带有可滚动子组件的组件 并且我想公开滚动的功能 const MyComponent props gt return