Detach connect function

This commit is contained in:
MrKBear 2022-03-20 14:52:05 +08:00
parent 8d5f2a7dfb
commit 3f4318e193
3 changed files with 39 additions and 33 deletions

View File

@ -3,16 +3,18 @@ import { Component, FunctionComponent, ReactNode, Consumer } from "react";
type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>; type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>;
function superConnect<C extends Emitter<E>, E extends Record<EventType, any>>( function superConnectWithEvent<C extends Emitter<E>, E extends Record<EventType, any>>(
consumer: Consumer<C> consumer: Consumer<C>, keyName: string
) { ) {
return (...events: Array<keyof E>) => { return (...events: Array<keyof E>) => {
return <R extends RenderComponent>(components: R): R => { return <R extends RenderComponent>(components: R): R => {
const C = components as any; const Components = components as any;
const Consumer = consumer;
return class extends Component<R> { return class extends Component<R> {
private status: C | undefined; private status: C | undefined;
private isEventMount: boolean = false; private isEventMount: boolean = false;
private propsObject: Record<string, C> = {};
private handelChange = () => { private handelChange = () => {
this.forceUpdate(); this.forceUpdate();
@ -37,12 +39,12 @@ function superConnect<C extends Emitter<E>, E extends Record<EventType, any>>(
} }
public render(): ReactNode { public render(): ReactNode {
const Consumer = consumer;
return <Consumer> return <Consumer>
{(status: C) => { {(status: C) => {
this.status = status; this.status = status;
this.propsObject[keyName] = status;
this.mountEvent(); this.mountEvent();
return <C {...this.props} status={status}></C>; return <Components {...this.props} {...this.propsObject}/>;
}} }}
</Consumer> </Consumer>
} }
@ -56,4 +58,21 @@ function superConnect<C extends Emitter<E>, E extends Record<EventType, any>>(
} }
} }
export { superConnect }; function superConnect<C extends Emitter<any>>(consumer: Consumer<C>, keyName: string) {
return <R extends RenderComponent>(components: R): R => {
return ((props: any) => {
const Components = components as any;
const Consumer = consumer;
return <Consumer>
{(status: C) => <Components
{...props}
{...{[keyName]: status}}
/>}
</Consumer>
}) as any;
}
}
export { superConnectWithEvent, superConnect };

View File

@ -1,4 +1,5 @@
import { createContext, Component, FunctionComponent } from "react"; import { createContext } from "react";
import { superConnect, superConnectWithEvent } from "./Context";
import { Emitter } from "@Model/Emitter"; import { Emitter } from "@Model/Emitter";
import { Layout } from "@Model/Layout"; import { Layout } from "@Model/Layout";
@ -12,9 +13,11 @@ enum Themes {
type Language = "ZH_CN" | "EN_US"; type Language = "ZH_CN" | "EN_US";
class Setting extends Emitter< interface ISettingEvents extends Setting {
Setting & {change: keyof Setting} change: keyof Setting;
> { }
class Setting extends Emitter<ISettingEvents> {
/** /**
* *
@ -51,21 +54,14 @@ SettingContext.displayName = "Setting";
const SettingProvider = SettingContext.Provider; const SettingProvider = SettingContext.Provider;
const SettingConsumer = SettingContext.Consumer; const SettingConsumer = SettingContext.Consumer;
type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>;
/** /**
* *
*/ */
function useSetting<R extends RenderComponent>(components: R): R { const useSetting = superConnect<Setting>(SettingConsumer, "setting");
return ((props: any) => {
const C = components; const useStatusWithEvent = superConnectWithEvent<Setting, ISettingEvents>(SettingConsumer, "setting");
return <SettingConsumer>
{(setting: Setting) => <C {...props} setting={setting}></C>}
</SettingConsumer>
}) as any;
}
export { export {
Themes, Setting, SettingContext, useSetting, Language, Themes, Setting, SettingContext, useSetting, Language, useStatusWithEvent,
IMixinSettingProps, SettingProvider, SettingConsumer IMixinSettingProps, SettingProvider, SettingConsumer
}; };

View File

@ -9,7 +9,7 @@ import { AbstractRenderer } from "@Model/Renderer";
import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer"; import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer";
import { Setting } from "./Setting"; import { Setting } from "./Setting";
import { I18N } from "@Component/Localization/Localization"; import { I18N } from "@Component/Localization/Localization";
import { superConnect } from "./Context"; import { superConnectWithEvent, superConnect } from "./Context";
function randomColor(unNormal: boolean = false) { function randomColor(unNormal: boolean = false) {
const color = [ const color = [
@ -259,21 +259,12 @@ StatusContext.displayName = "Status";
const StatusProvider = StatusContext.Provider; const StatusProvider = StatusContext.Provider;
const StatusConsumer = StatusContext.Consumer; const StatusConsumer = StatusContext.Consumer;
type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>;
/** /**
* *
*/ */
function useStatus<R extends RenderComponent>(components: R): R { const useStatus = superConnect<Status>(StatusConsumer, "status");
return ((props: any) => {
const C = components;
return <StatusConsumer>
{(status: Status) => <C {...props} status={status}></C>}
</StatusConsumer>
}) as any;
}
const useStatusWithEvent = superConnect<Status, IStatusEvent>(StatusConsumer); const useStatusWithEvent = superConnectWithEvent<Status, IStatusEvent>(StatusConsumer, "status");
export { export {
Status, StatusContext, useStatus, useStatusWithEvent, Status, StatusContext, useStatus, useStatusWithEvent,