Quelle est la différence entre ForwardRefExoticComponent et ForwardRefRenderFunction dans React?

Oct 07 2020

J'écris un composant React qui peut transmettre la référence à ses enfants

J'ai découvert que pour le type de retour des composants de fonction, je peux utiliser ForwardRefExoticComponent et ForwardRefRenderFunction . Mais je ne suis pas sûr de la différence entre eux.

Jusqu'à présent, lors de l'utilisation de ForwardRefExoticComponent , je peux l'étendre alors que ForwardRefRenderFunction ne le peut pas? J'ai posté une question liée à mon cas ici: Comment exporter forwardRef avec ForwardRefRenderFunction

Si quelqu'un sait quelle est la différence entre eux et ce qu'ils font, aidez-moi. Parce qu'il semble que l'équipe React n'a aucun document à leur sujet (mais ils sont à l'intérieur du package react)

Réponses

4 PeterLehnhardt Oct 07 2020 at 14:19

ForwardRefExoticComponent

La définition tirée d' ici est

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

Si vous l'écrivez, vous obtenez

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

La définition tirée d' ici est

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

Différences

  • ForwardRefRenderFunctionne prend pas en charge propTypeset defaultProps, alors que le ForwardRefExoticComponentfait.
  • ForwardRefExoticComponenta un membre supplémentaire $$typeofde typesymbol
  • La signature d'appel de ForwardRefRenderFunctionprend un propsobjet, qui doit inclure un membre childrenet un objet ref en tant que paramètres, tandis que la signature d'appel de ForwardRefExoticComponentprend uniquement un objet props de forme arbitraire comme paramètre.

Quelques réflexions supplémentaires

L'interaction de ces deux définitions est mieux vue dans la définition de la forwardReffonction :

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

En outre, une grande différence entre les deux définitions semble être que ForwardRefExoticComponent(comme tous les composants exotiques) ne sont pas des composants de fonction, mais en fait juste des objets, qui sont traités spécialement lors de leur rendu. Par conséquent, le commentaire

REMARQUE : les composants exotiques ne sont pas appelables.

Et pour une raison quelconque, ces composants exotiques sont nécessaires à certains endroits.