React中React.forwardRef的使用方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React中React.forwardRef的使用方式相关的知识,希望对你有一定的参考价值。

参考技术A 一、众多周知可以forwardRef可以转发ref属性
比如要在父组件中调用子组件中某个DOM节点或者组件的ref

二、除开传递ref值,还可以巧妙的传递自己想要的值,例如调用三方组件,三方组件接受一个自定义组件,想要在自定义组件获取额外的props。比如num,以下这种方式就不好处理。

当然你也可以用redux,但是仅仅为了取一个值就用redux开销有点大, 这儿我们就可以巧妙的使用React.forwardRef,修改Father组件

这样在Content组件中既可以获取Child组件中flag也可以获取Father组件中传递的num

最后的结果

我如何使用 jsdoc 注释注释 React.forwardRef 以便智能感知可以显示在底层组件中?

【中文标题】我如何使用 jsdoc 注释注释 React.forwardRef 以便智能感知可以显示在底层组件中?【英文标题】:How do i annotate React.forwardRef with jsdoc comments so that intellisense can show up for the underlying component? 【发布时间】:2021-06-07 17:33:27 【问题描述】:

我有一个这样写成函数的 React 组件:

function Button( text, icon ) 
  return ...


Button.propTypes = 
  text: PropTypes.string.isRequired,
  icon: PropTypes.string.isRequired

当使用这个组件时,我在 vscode 中得到了自动补全/智能感知

如果我将此组件包装在 React.forwardRef 中, export default React.forwardRef((props, ref) => <Button btnRef=ref ...props />)

然后我得到 forwardRef 函数的智能感知,这对我的使用没有帮助,因为现在我无法让道具自动完成/显示在智能感知中。

我尝试使用 jsdoc extends / augments 注释 React.forwardRef 但没有成功,在这种情况下,即使 forwardRef 使用的默认智能感知也停止显示。 (我相信这是因为 vscode 比 jsdoc cmets 更偏爱可用类型)。有没有办法让我获得与未包装组件类似的包装组件的智能感知?这与我对以与未包装组件类似的方式使用包装组件的理解一致。

【问题讨论】:

我知道如何在 typescript 中执行此操作,但我不知道仅使用 JSDoc 会是什么样子。不过,您似乎希望在 Button 上包含 btnRef 作为道具。 是的,btnRef 将是按钮的道具 【参考方案1】:

这取决于你想对这些类型有多迂腐。通常,这些组件的使用与其他功能组件几乎相同,因此最简单的方法是将结果的类型声明为功能组件。 props 的技巧是首先为 prop 类型创建一个变量,然后为泛型类型引用该变量(或者至少,我还没有找到一种方法让它在没有间隙值的情况下工作):

/**
 * @type React.FC<ButtonPropTypes>
 */
const Button = forwardRef(( text, icon , ref) => (
  <button ref=ref>texticon</button>
))

const ButtonPropTypes = 
  text: string.isRequired,
  icon: string.isRequired,
  // `ref` isn't a "real" prop, so `prop-types` will not not actually validate
  // this one, but this adds it to the intellisense list if desired. Feel
  // free to just omit it.
  ref: oneOf(shape( current: any ), func),


Button.propTypes = ButtonPropTypes

如果要更准确,forwardRef的返回类型其实是:

/**
 * @type React.ForwardRefRenderFunction<HTMLButtonElement, ButtonPropTypes>
 */
const Button = forwardRef(( text, icon , ref) => (
  <button ref=ref>texticon</button>
))

const ButtonPropTypes = 
  text: string.isRequired,
  icon: string.isRequired,


Button.propTypes = ButtonPropTypes

但是,IntelliSense 似乎无法识别 ref 属性(工作正常,只是不在列表中)。

类型的定义在这里: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/3423b4fc3e3da09f8acc386bc2fee6fb8f5e0880/types/react/index.d.ts#L559 第一个参数是将分配给 ref 的值的预期类型。但是,由于您实际上并没有静态输入无论如何都会传入的ref,因此您可以选择用? 省略那个:

/**
 * @type React.ForwardRefRenderFunction<?, ButtonPropTypes>
 */

认为你对最后一部分的意思是你不会同时拥有未包装和包装的版本。这是典型的模式,因为保留两者并没有真正的用处。但是,顺便说一句,您可以直接引用任何其他组件的 propTypes 值以用作泛型类型,例如:

/**
 * @type React.FC<UnWrappedButton.propTypes>
 */

【讨论】:

这似乎至少适用于我的特定用例。万分感谢!现在我只需要了解为什么 @type 注释有效但不能扩充/扩展,我将其用于一般未包装的组件 谢谢你,埃里希!我是这样使用它的:@type React.ForwardRefRenderFunction&lt;React.FunctionComponent, ButtonPropTypes&gt;,它就像一个魅力。 您可能不希望React.FunctionComponent 作为第一个通用参数。该参数用于存储在提供的ref 中的任何内容,它始终是某种DOM 元素。所以例如在上面的示例中,ref 包含button 的实际 HTML DOM 元素。第一个参数在很大程度上被智能感知忽略了,这就是为什么我建议您可以只使用 ? 的原因,但为了文档的准确性,它将是封装的原生元素类型。

以上是关于React中React.forwardRef的使用方式的主要内容,如果未能解决你的问题,请参考以下文章

在没有道具的 Typescript 中使用 React.forwardRef

React Ref 和 React forwardRef

将 React forwardRef 与 Redux 连接一起使用

[react] 什么是React.forwardRef?它有什么作用?

我如何使用 jsdoc 注释注释 React.forwardRef 以便智能感知可以显示在底层组件中?

带有 React.forwardRef 功能组件的 VSCode TS 错误