Cara mengekspor forwardRef dengan ForwardRefRenderFunction

Oct 06 2020

Saya memiliki komponen yang termasuk dalam pustaka UI, sebut saja komponen Input. Saat menggunakan pustaka ini untuk memanggil Input, ada banyak tipe yang bisa saya panggil. Sebagai contoh

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

Sekarang saya ingin menulis pembungkus untuk komponen Input ini, jadi saya menulis seperti ini

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;

di index.tsx

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

Lalu saya bisa menggunakannya seperti ini:

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

Tetapi dengan melakukan ini, saya tidak dapat menggunakan metode ref dari pustaka UI asli (seperti inputRef.current.focus()). itulah mengapa saya menggunakan forwardRef dan ForwardRefRenderFunction seperti ini

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

Dengan mengubahnya ke ini, saya bisa meneruskan ref ke perpustakaan UI asli dan dapat menggunakan metode aslinya. Namun, masalah saya saat ini adalah ketika saya mengubah ke forwardRef dan ForwardRefRenderFunction , saya tidak dapat memanggil TextArea dan Search lagi.

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

Ini adalah kesalahannya:

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.

Adakah yang bisa memberi saya petunjuk tentang ini? Terima kasih

Jawaban

1 PeterLehnhardt Oct 07 2020 at 07:23

Apa yang Anda lakukan adalah:

  1. Tentukan fungsi InputWrappersebagai tipeInputWrapperComponent
  2. Tentukan Searchdan TextAreasebagai anggotaInputWrapper
  3. Buat komponen penerusan ref dengan forwardRef

Masalahnya adalah, itu forwardRefmembuat komponen yang benar-benar baru dan tidak peduli, apakah sudah ada beberapa sub-komponen yang ditentukan sebelumnya. Mereka hanya akan dibuang dan Anda mendapatkan kesalahan dari anggota tersebut yang tidak ditentukan.

Jadi cara untuk melakukannya sebenarnya:

  1. Tentukan fungsi InputWrappersebagai tipeInputWrapperComponent
  2. Buat komponen penerusan ref dengan forwardRef
  3. Tentukan Searchdan TextAreasebagai anggota komponen penerusan ref baru
1 JakeLam Oct 07 2020 at 05:32

Saya akhirnya menggunakan ForwardRefExoticComponent daripada ForwardRefRenderFunction

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

Tapi saya benar-benar tidak yakin apa perbedaan di antara mereka

Pembaruan : Silakan periksa jawaban Peter.

Untuk apa sih perbedaan keduanya, silahkan cek jawabannya disini: Apa perbedaan ForwardRefExoticComponent dan ForwardRefRenderFunction dalam bereaksi?