Test Consumer Provider

This commit is contained in:
MrKBear 2022-02-23 17:51:20 +08:00
parent 669d104eb3
commit 0eb0b6f7f5
5 changed files with 127 additions and 3 deletions

View File

@ -0,0 +1,44 @@
import { Component, ReactNode } from "react";
import { useSetting, IMixinSettingProps, Themes } from "@Context/Setting";
interface IHeaderBarProps {}
/**
*
*/
@useSetting
class HeaderBar extends Component<IHeaderBarProps & IMixinSettingProps> {
private handelClick = () => {
if (this.props.setting) {
this.props.setting.setProps("themes",
this.props.setting.themes === Themes.dark ? Themes.light : Themes.dark
);
}
}
private changeListener = () => {
this.forceUpdate();
}
public componentDidMount() {
console.log("mount");
if (this.props.setting) {
this.props.setting.on("change", this.changeListener);
}
}
public componentWillUnmount() {
console.log("die");
if (this.props.setting) {
this.props.setting.off("change", this.changeListener);
}
}
public render(): ReactNode {
return <div onClick={this.handelClick}>{this.props.setting?.themes}</div>
}
}
export default HeaderBar;
export { HeaderBar };

View File

@ -0,0 +1,58 @@
import { createContext, Component, FunctionComponent } from "react";
import { Emitter } from "@Model/Emitter";
/**
*
*/
enum Themes {
light = 1,
dark = 2
}
class Setting extends Emitter<
Setting & {change: keyof Setting}
> {
/**
*
*/
public themes: Themes = Themes.light;
/**
*
*/
public setProps<P extends keyof Setting>(key: P, value: Setting[P]) {
this[key] = value as any;
this.emit("change", key);
this.emit(key as any, value as any);
}
}
interface IMixinSettingProps {
setting?: Setting;
}
const SettingContext = createContext<Setting>(new Setting());
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;
}
export {
Themes, Setting, SettingContext, useSetting,
IMixinSettingProps, SettingProvider, SettingConsumer
};

View File

@ -1,13 +1,28 @@
import { Component, ReactNode, createRef } from "react"; import { Component, ReactNode } from "react";
import { SettingProvider, Setting } from "@Context/Setting";
import { HeaderBar } from "@Component/HeaderBar/HeaderBar";
import { Entry } from "../Entry/Entry"; import { Entry } from "../Entry/Entry";
import "./SimulatorWeb.scss"; import "./SimulatorWeb.scss";
class SimulatorWeb extends Component { class SimulatorWeb extends Component {
private canvasContRef = createRef<HTMLDivElement>(); /**
*
*/
private setting: Setting;
public constructor(props: any) {
super(props);
// TODO: 这里要读取设置
this.setting = new Setting();
(window as any).setting = (this.setting as any);
}
public render(): ReactNode { public render(): ReactNode {
return <div>Web</div> return <SettingProvider value={this.setting}>
<HeaderBar/>
</SettingProvider>
} }
} }

View File

@ -1,6 +1,7 @@
{ {
"compileOnSave": true, "compileOnSave": true,
"compilerOptions": { "compilerOptions": {
"experimentalDecorators": true,
"alwaysStrict": true, "alwaysStrict": true,
"strict": true, "strict": true,
"sourceMap": true, "sourceMap": true,
@ -23,6 +24,12 @@
], ],
"@GLRender/*": [ "@GLRender/*": [
"./source/GLRender/*" "./source/GLRender/*"
],
"@Context/*": [
"./source/Context/*"
],
"@Component/*": [
"./source/Component/*"
] ]
} }
}, },