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>;
function superConnect<C extends Emitter<E>, E extends Record<EventType, any>>(
consumer: Consumer<C>
function superConnectWithEvent<C extends Emitter<E>, E extends Record<EventType, any>>(
consumer: Consumer<C>, keyName: string
) {
return (...events: Array<keyof E>) => {
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> {
private status: C | undefined;
private isEventMount: boolean = false;
private propsObject: Record<string, C> = {};
private handelChange = () => {
this.forceUpdate();
@ -37,12 +39,12 @@ function superConnect<C extends Emitter<E>, E extends Record<EventType, any>>(
}
public render(): ReactNode {
const Consumer = consumer;
return <Consumer>
{(status: C) => {
this.status = status;
this.propsObject[keyName] = status;
this.mountEvent();
return <C {...this.props} status={status}></C>;
return <Components {...this.props} {...this.propsObject}/>;
}}
</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 { Layout } from "@Model/Layout";
@ -12,9 +13,11 @@ enum Themes {
type Language = "ZH_CN" | "EN_US";
class Setting extends Emitter<
Setting & {change: keyof Setting}
> {
interface ISettingEvents extends Setting {
change: keyof Setting;
}
class Setting extends Emitter<ISettingEvents> {
/**
*
@ -51,21 +54,14 @@ SettingContext.displayName = "Setting";
const SettingProvider = SettingContext.Provider;
const SettingConsumer = SettingContext.Consumer;
type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>;
/**
*
*/
function useSetting<R extends RenderComponent>(components: R): R {
return ((props: any) => {
const C = components;
return <SettingConsumer>
{(setting: Setting) => <C {...props} setting={setting}></C>}
</SettingConsumer>
}) as any;
}
const useSetting = superConnect<Setting>(SettingConsumer, "setting");
const useStatusWithEvent = superConnectWithEvent<Setting, ISettingEvents>(SettingConsumer, "setting");
export {
Themes, Setting, SettingContext, useSetting, Language,
Themes, Setting, SettingContext, useSetting, Language, useStatusWithEvent,
IMixinSettingProps, SettingProvider, SettingConsumer
};

View File

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