如何使用 ForwardRefRenderFunction 导出 forwardRef

IT技术 javascript reactjs typescript react-forwardref
2021-05-14 02:52:13

我有一个属于 UI 库的组件,我们称之为输入组件。使用这个库调用 Input 时,可以调用的类型很多。例如

<Input />
<Input.TextArea />
<Input.Search />

现在我想给这个 Input 组件写一个包装器,所以我这样写

type InputWrapperComponent = FC<InputProps> & {
  Search: typeof Input.Search;
  TextArea: typeof Input.TextArea;
};

const InputWrapper: InputWrapperComponent = (props) => {
  // make some minor changes here
}

InputWrapper.Search = Input.Search;
InputWrapper.TextArea = Input.TextArea;
export default InputWrapper;

index.tsx 中

export { default as InputWrapper } from './input';

然后我可以像这样使用它们:

<InputWrapper />. --> Works
<InputWrapper.TextArea />. --> Works
<InputWrapper.Search />. --> Works

但是通过这样做,我无法使用原始 UI 库的ref方法(例如inputRef.current.focus())。这就是为什么我像这样使用forwardRefForwardRefRenderFunction

type InputWrapperComponent = ForwardRefRenderFunction<HTMLInputElement, InputProps> & {
  Search: typeof Input.Search;
  TextArea: typeof Input.TextArea;
};

const InputWrapper: InputWrapperComponent = (props, ref) => {
  // make some minor changes here and add the ref to the input
}

InputWrapper.Search = Input.Search;
InputWrapper.TextArea = Input.TextArea;
export default forwardRef(InputWrapper);

通过更改为这个,我可以将 ref 传递给原始 UI 库并可以使用其原始方法。然而,现在我的问题是,当我改变forwardRefForwardRefRenderFunction,我不能把文本区,并搜索

<InputWrapper />. --> Works
<InputWrapper.TextArea />. --> Error
<InputWrapper.Search />. --> Error

这是错误:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

任何人都可以给我一些指导吗?谢谢

2个回答

你正在做的是:

  1. 将函数定义InputWrapper为类型InputWrapperComponent
  2. 定义SearchTextArea作为成员InputWrapper
  3. 创建一个引用转发组件 forwardRef

问题是,这forwardRef会创建一个全新的组件,并且不关心之前是否定义了一些子组件。它们只会被扔掉,你会得到这些成员未定义的错误。

所以要走的路实际上是:

  1. 将函数定义InputWrapper为类型InputWrapperComponent
  2. 创建一个引用转发组件 forwardRef
  3. 定义SearchTextArea作为新的 ref 转发组件的成员

我最终使用 ForwardRefExoticComponent 而不是 ForwardRefRenderFunction

type InputWrapperComponent = React.ForwardRefExoticComponent<
  React.PropsWithoutRef<InputProps> & React.RefAttributes<HTMLInputElement>
> & {
  Search: typeof Input.Search;
  TextArea: typeof Input.TextArea;
  Password: typeof Input.Password;
};

但我真的不确定它们之间有什么区别

更新:请检查彼得的回答。

关于两者之间的区别,请在这里查看他的回答: react中 ForwardRefExoticComponent 和 ForwardRefRenderFunction 的区别是什么?