78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
import { Component, FunctionComponent, ReactNode, Consumer } from "react";
|
|
import { Emitter, EventType } from "@Model/Emitter";
|
|
|
|
type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>;
|
|
|
|
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 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();
|
|
}
|
|
|
|
private mountEvent() {
|
|
if (this.status && !this.isEventMount) {
|
|
this.isEventMount = true;
|
|
console.log("Component dep event mount: " + events.join(", "));
|
|
for (let i = 0; i < events.length; i++) {
|
|
this.status.on(events[i], this.handelChange);
|
|
}
|
|
}
|
|
}
|
|
|
|
private unmountEvent() {
|
|
if (this.status) {
|
|
for (let i = 0; i < events.length; i++) {
|
|
this.status.off(events[i], this.handelChange);
|
|
}
|
|
}
|
|
}
|
|
|
|
public render(): ReactNode {
|
|
return <Consumer>
|
|
{(status: C) => {
|
|
this.status = status;
|
|
this.propsObject[keyName] = status;
|
|
this.mountEvent();
|
|
return <Components {...this.props} {...this.propsObject}/>;
|
|
}}
|
|
</Consumer>
|
|
}
|
|
|
|
public componentWillUnmount() {
|
|
this.unmountEvent();
|
|
}
|
|
|
|
} as any;
|
|
}
|
|
}
|
|
}
|
|
|
|
function superConnect<C>(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 }; |