Como exportar forwardRef com ForwardRefRenderFunction
Estou tendo um componente que pertence a uma biblioteca de interface do usuário, vamos chamá-lo de componente de entrada. Ao usar esta biblioteca para chamar Input, há muitos tipos que posso chamar. Por exemplo
<Input />
<Input.TextArea />
<Input.Search />
Agora eu quero escrever um wrapper para este componente de entrada, então escrevo assim
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;
em index.tsx
export { default as InputWrapper } from './input';
Então posso usá-los assim:
<InputWrapper />. --> Works
<InputWrapper.TextArea />. --> Works
<InputWrapper.Search />. --> Works
Mas, ao fazer isso, não posso usar métodos ref da biblioteca UI original (algo como inputRef.current.focus()). é por isso que eu uso forwardRef e ForwardRefRenderFunction assim
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);
Ao mudar para isso, posso passar o ref para a biblioteca de interface do usuário original e usar seus métodos originais. No entanto, o meu problema agora é quando eu mudar para forwardRef e ForwardRefRenderFunction , eu não posso chamar TextArea e Pesquisar mais
<InputWrapper />. --> Works
<InputWrapper.TextArea />. --> Error
<InputWrapper.Search />. --> Error
Este é o erro:
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.
Alguém pode me dar alguma orientação sobre isso? obrigado
Respostas
O que você está fazendo é:
- Definir função
InputWrappercomo tipoInputWrapperComponent - Definir
SearcheTextAreacomo membros deInputWrapper - Crie um componente de encaminhamento de referência com
forwardRef
O problema é que isso forwardRefcria um componente completamente novo e não se importa se houve alguns subcomponentes definidos antes. Eles serão jogados fora e você terá o erro de esses membros serem indefinidos.
Portanto, o caminho a seguir é:
- Definir função
InputWrappercomo tipoInputWrapperComponent - Crie um componente de encaminhamento de referência com
forwardRef - Definir
SearcheTextAreacomo membros do novo componente de encaminhamento de referência
Acabo usando ForwardRefExoticComponent em vez de ForwardRefRenderFunction
type InputWrapperComponent = React.ForwardRefExoticComponent<
React.PropsWithoutRef<InputProps> & React.RefAttributes<HTMLInputElement>
> & {
Search: typeof Input.Search;
TextArea: typeof Input.TextArea;
Password: typeof Input.Password;
};
Mas eu realmente não tenho certeza qual é a diferença entre eles
Atualização : verifique a resposta de Peter.
Para qual é a diferença entre os dois, verifique sua resposta aqui: Qual é a diferença entre ForwardRefExoticComponent e ForwardRefRenderFunction em react?