ForwardRefRenderFunctionを使用してforwardRefをエクスポートする方法

Oct 06 2020

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())を使用できなくなります。だから私はこのようにforwardRefとForwardRefRenderFunctionを使用します

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);

これに変更することで、参照を元のUIライブラリに渡し、元のメソッドを使用できます。しかし、今の私の問題は、私が変更したときであるforwardRefとForwardRefRenderFunction、私は呼び出すことはできませんの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.

誰でも私にこれについていくつかのガイダンスを与えることができますか?ありがとう

回答

1 PeterLehnhardt Oct 07 2020 at 07:23

あなたがしていることは:

  1. 関数InputWrapperをタイプとして定義するInputWrapperComponent
  2. のメンバーとして定義SearchしますTextAreaInputWrapper
  3. で参照転送コンポーネントを作成します forwardRef

問題は、それforwardRefが完全に新しいコンポーネントを作成し、以前に定義されたサブコンポーネントがあったかどうかを気にしないことです。それらはただ捨てられ、あなたはそれらのメンバーが未定義であるというエラーを受け取ります。

したがって、実際に進む方法は次のとおりです。

  1. 関数InputWrapperをタイプとして定義するInputWrapperComponent
  2. で参照転送コンポーネントを作成します forwardRef
  3. 新しいref転送コンポーネントのメンバーとして定義SearchしTextAreaます
1 JakeLam Oct 07 2020 at 05:32

ForwardRefRenderFunctionの代わりにForwardRefExoticComponentを使用することになります

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

しかし、私はそれらの違いが何であるか本当にわかりません

更新:ピーターの答えを確認してください。

2つの違いについては、ここで彼の答えを確認してください:ReactのForwardRefExoticComponentとForwardRefRenderFunctionの違いは何ですか?