如何使用 ForwardRefRenderFunction 导出 forwardRef

How to export forwardRef with ForwardRefRenderFunction

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

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

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

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 库(例如 inputRef.current.focus() )的 ref 方法。这就是为什么我像这样使用 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 时,我无法调用 TextArea再搜索

<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.

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

我最终使用 ForwardRefExoticComponent 而不是 ForwardRefRenderFunction

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

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

更新:请检查Peter的回答。

两者有什么区别,请看他的回答:

你正在做的是:

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

问题是,forwardRef 创建了一个全新的组件并且不关心之前是否已经定义了一些 sub-components。它们将被丢弃,你会得到这些成员未定义的错误。

所以要走的路实际上是:

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