Improves lazy loading.

This commit is contained in:
Henning Dieterichs
2020-10-08 10:50:19 +02:00
parent 5512c0b244
commit cf382c71c9
33 changed files with 498 additions and 280 deletions

View File

@@ -1,29 +1,30 @@
import * as React from "react";
import { observable, runInAction } from "mobx";
import { observer } from "mobx-react";
import { Loadable } from "./Loadable";
export function makeLazyLoadable<TProps>(
selector: () => Promise<React.ComponentClass<TProps>>
): React.ComponentClass<TProps> {
): React.ComponentClass<TProps> & { preload(): Promise<void> } {
const loader = new Loadable(selector);
@observer
class MyComponent extends React.Component<TProps> {
@observable
component: React.ComponentClass<TProps> | undefined;
async componentDidMount() {
const result = await selector();
runInAction("Set Lazily Loaded Component", () => {
this.component = result;
});
constructor(props: any) {
super(props);
loader.load();
}
render() {
if (!this.component) {
if (!loader.result) {
return <div>Loading...</div>;
}
const C = this.component;
const C = loader.result;
return <C {...this.props} />;
}
static async preload(): Promise<void> {
await loader.load();
}
}
return MyComponent;

View File

@@ -0,0 +1,22 @@
import { observable, runInAction } from "mobx";
export class Loadable<T> {
@observable.ref
public result: T | undefined;
private operation?: Promise<void> = undefined;
constructor(private readonly _load: () => Promise<T>) {}
public load(): Promise<void> {
if (!this.operation) {
this.operation = (async () => {
const r = await this._load();
runInAction(() => {
this.result = r;
});
})();
}
return this.operation;
}
}