В чем разница между ForwardRefExoticComponent и ForwardRefRenderFunction в React?

Oct 07 2020

Я пишу компонент React, который может пересылать ссылку своим детям

Я обнаружил, что в качестве возвращаемого типа компонентов функции я могу использовать ForwardRefExoticComponent и ForwardRefRenderFunction . Но я не уверен, в чем разница между ними.

Пока что при использовании ForwardRefExoticComponent я могу его расширить, а ForwardRefRenderFunction - нет? Я разместил здесь вопрос, связанный с моим случаем: Как экспортировать forwardRef с помощью ForwardRefRenderFunction

Если кто-нибудь знает, в чем разница между ними и тем, что они делают, пожалуйста, помогите мне. Потому что кажется, что у команды React нет документа о них (но они находятся внутри пакета реакции)

Ответы

4 PeterLehnhardt Oct 07 2020 at 14:19

ForwardRefExoticComponent

Определение, взятое отсюда :

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

Если вы это напишете, вы получите

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

Определение, взятое отсюда :

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

Отличия

  • ForwardRefRenderFunctionне поддерживает propTypesи defaultProps, тогда как ForwardRefExoticComponentподдерживает.
  • ForwardRefExoticComponentимеет дополнительный член $$typeofтипаsymbol
  • Сигнатура вызова ForwardRefRenderFunctionпринимает propsобъект, который должен включать в себя член childrenи объект ref в качестве параметров, тогда как подпись вызова ForwardRefExoticComponentпринимает только объект props произвольной формы в качестве параметра.

Еще несколько мыслей

Взаимодействие этих двух определений лучше всего видно в определении forwardRefфункции :

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

Кроме того, большая разница между этими двумя определениями заключается в том, что ForwardRefExoticComponent(как и все экзотические компоненты) не являются функциональными компонентами, а фактически являются просто объектами, которые обрабатываются особым образом при их рендеринге. Поэтому комментарий

ПРИМЕЧАНИЕ . Экзотические компоненты не вызываются.

И по какой-то причине эти экзотические компоненты кое-где необходимы.