В настоящее время у меня есть контекст под названием 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
?