Написание «фабрики функций HoC factory» для общих потребителей контекста React - PullRequest
0 голосов
/ 31 декабря 2018

В настоящее время у меня есть контекст под названием ExploreContext, к которому я обращаюсь, вставляя соответствующие реквизиты в определенный компонент, используя фабричную функцию HoC, которая выглядит следующим образом:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type Optionalize<T extends K, K> = Omit<T, keyof K>;

export type WithExploreContextProps = { exploreContext: IExploreContextStore };

export function withExploreContext<P extends WithExploreContextProps = WithExploreContextProps>(
    WrappedComponent: ComponentType<P>
) {
    const displayName = WrappedComponent.displayName || WrappedComponent.name || "Component";

    return class ComponentWithContext extends Component<Optionalize<P, WithExploreContextProps>> {
        public static displayName = `withExploreContext(${displayName})`;

        public render() {
            return (
                <Consumer>{(context) => <WrappedComponent {...this.props as P} exploreContext={context} />}</Consumer>
            );
        }
    };
}

Этот работает отлично,но я собирался написать общую фабричную функцию для создания таких фабрик HoC и уменьшения дублирования кода.Важно то, что я хотел не вызывать введенный контекст просто context, а дать ему более конкретное имя.Поэтому я нашел следующее решение:

export function createWithContext<WithProps, ContextStore>(
    ConsumerComponent: ExoticComponent<ConsumerProps<ContextStore>>,
    contextKey: keyof WithProps
) {
    return <P extends WithProps = WithProps>(WrappedComponent: ComponentType<P>) => {
        return class ComponentWithContext extends Component<Optionalize<P, WithProps>> {
            public render() {
                return (
                    <ConsumerComponent>
                        {(context) => {
                            const props: P & WithProps = { ...(this.props as P), [contextKey]: context };
                            return <WrappedComponent {...props} />;
                        }}
                    </ConsumerComponent>
                );
            }
        };
    };
}

Эта конкретная реализация позволяет мне довольно легко написать следующее:

export const withExploreContext = createWithContext<WithExploreContextProps, IExploreContextStore>(
    Consumer,
    "exploreContext"
);

, которое даже статически проверяется.Мне было любопытно, существует ли более элегантный способ реализации такой «фабрики функций HoC factory».Особенно необходимость в явном IExploreContextStore как параметре второго типа слишком многословна для меня, так как я создаю типы контекста следующим образом:

const { Consumer, Provider } = createContext<IExploreContextStore>({} as IExploreContextStore);

Какие-нибудь лучшие решения для упрощения функции createWithContext?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...