Qual é a diferença entre ForwardRefExoticComponent e ForwardRefRenderFunction em react?

Oct 07 2020

Estou escrevendo um componente React que pode encaminhar ref para seus filhos

Descobri que, para o tipo de retorno dos componentes da função, posso usar ForwardRefExoticComponent e ForwardRefRenderFunction . Mas não tenho certeza de qual é a diferença entre eles.

Até agora, ao usar ForwardRefExoticComponent , posso estendê-lo enquanto o ForwardRefRenderFunction não pode? Eu postei uma pergunta relacionada ao meu caso aqui: Como exportar forwardRef com ForwardRefRenderFunction

Se alguém souber qual é a diferença entre eles e o que fazem por favor me ajude. Porque parece que a equipe React não tem nenhum documento sobre eles (mas eles estão dentro do pacote de reação)

Respostas

4 PeterLehnhardt Oct 07 2020 at 14:19

ForwardRefExoticComponent

A definição tirada daqui é

interface ExoticComponent<P = {}> {
    /**
     * **NOTE**: Exotic components are not callable.
     */
    (props: P): (ReactElement|null);
    readonly $$typeof: symbol;
}

interface NamedExoticComponent<P = {}> extends ExoticComponent<P> {
    displayName?: string;
}

interface ForwardRefExoticComponent<P> extends NamedExoticComponent<P> {
    defaultProps?: Partial<P>;
    propTypes?: WeakValidationMap<P>;
}

Se você escrever, você obterá

interface ForwardRefExoticComponent<P> {
    /**
     * **NOTE**: Exotic components are not callable.
     */
    (props: P): (ReactElement|null);
    readonly $$typeof: symbol;
    displayName?: string;
    defaultProps?: Partial<P>;
    propTypes?: WeakValidationMap<P>;
}

ForwardRefRenderFunction

A definição tirada daqui é

interface ForwardRefRenderFunction<T, P = {}> {
    (props: PropsWithChildren<P>, ref: ((instance: T | null) => void) | MutableRefObject<T | null> | null): ReactElement | null;
    displayName?: string;
    // explicit rejected with `never` required due to
    // https://github.com/microsoft/TypeScript/issues/36826
    /**
     * defaultProps are not supported on render functions
     */
    defaultProps?: never;
    /**
     * propTypes are not supported on render functions
     */
    propTypes?: never;
}

Diferenças

  • ForwardRefRenderFunctionnão suporta propTypese defaultProps, ao passo que ForwardRefExoticComponentsim.
  • ForwardRefExoticComponenttem um membro adicional $$typeofdo tiposymbol
  • A assinatura de chamada de ForwardRefRenderFunctionleva um propsobjeto, que deve incluir um childrenobjeto membro e um objeto ref como parâmetros, enquanto a assinatura de chamada de ForwardRefExoticComponentapenas leva um objeto de adereços de forma arbitrária como parâmetro.

Mais alguns pensamentos

A interação dessas duas definições é melhor vista na definição da forwardReffunção :

function forwardRef<T, P = {}>(render: ForwardRefRenderFunction<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;

Além disso, uma grande diferença entre as duas definições parece ser que ForwardRefExoticComponent(como todos os componentes exóticos) não são componentes de função, mas na verdade apenas objetos, que são tratados de maneira especial ao renderizá-los. Portanto, o comentário

NOTA : Os componentes exóticos não podem ser chamados.

E por alguma razão, esses componentes exóticos são necessários em alguns lugares.