为通用React上下文使用者编写“ HoC工厂功能工厂”

时间:2018-12-31 12:36:09

标签: reactjs typescript higher-order-components

目前,我有一个名为DWORD * x = (DWORD*)(ptr1 + sizeof(int) + sizeof(float)); float f = *(float*)x; 的上下文,可以通过使用HoC工厂函数将各个道具注入到特定组件中来访问该上下文,如下所示:

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> ); } }; } ,而是给它一个更具体的名称。因此,我想出了以下解决方案:

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

,甚至被静态检查。不过,我很好奇,是否存在一种更优雅的方式来实现这样的“ HoC工厂功能工厂”。特别是对于显式export const withExploreContext = createWithContext<WithExploreContextProps, IExploreContextStore>( Consumer, "exploreContext" ); 作为第二个类型参数的必要性,对我来说太冗长了,因为我按如下方式创建了上下文类型:

IExploreContextStore

有没有更好的解决方案来简化const { Consumer, Provider } = createContext<IExploreContextStore>({} as IExploreContextStore); 函数?

0 个答案:

没有答案