Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(flat-pages): replace loadable component with suspense #1973

Merged
merged 1 commit into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 17 additions & 34 deletions packages/flat-pages/src/AppRoutes/AppRouteContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { ComponentType, useContext, useEffect } from "react";
import React, { ComponentType, useContext, useEffect, lazy, Suspense } from "react";
import { observer } from "mobx-react-lite";
import loadable from "@loadable/component";
import { useTranslate } from "@netless/flat-i18n";
import { FlatThemeBodyProvider, LoadingPage } from "flat-components";
import { RouteComponentProps } from "react-router-dom";
import { Redirect, RouteComponentProps } from "react-router-dom";
import { useIsomorphicLayoutEffect } from "react-use";
import { PageStoreContext, PreferencesStoreContext } from "../components/StoreProvider";
import { RouteNameType } from "../route-config";
Expand All @@ -14,27 +13,17 @@ import { WeChatRedirect } from "./WeChatRedirect";

export interface AppRouteContainerProps {
name: RouteNameType;
Comp: () => Promise<{ default: ComponentType<any> }>;
title: string;
routeProps: RouteComponentProps;
}

const componentCache = new Map<RouteNameType, ComponentType<any>>();
// Preload components every 2 seconds.
const preloadComponents = async (): Promise<void> => {
for (const name of Object.keys(routePages) as RouteNameType[]) {
if (!componentCache.has(name)) {
const { default: Component } = await routePages[name].component();
componentCache.set(name, Component);
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
};
window.setTimeout(preloadComponents, 5000);
const lazyPages: Record<string, ComponentType<any>> = {};
for (const name of Object.keys(routePages) as RouteNameType[]) {
lazyPages[name] = lazy(routePages[name].component);
}

export const AppRouteContainer = observer<AppRouteContainerProps>(function AppRouteContainer({
name,
Comp,
title,
routeProps,
}) {
Expand All @@ -53,14 +42,6 @@ export const AppRouteContainer = observer<AppRouteContainerProps>(function AppRo
window.getSelection()?.removeAllRanges();
}, [t, title]);

useEffect(() => {
if (!componentCache.has(name)) {
Comp().then(({ default: Component }) => {
componentCache.set(name, Component);
});
}
}, [Comp, name]);

const hasHeader =
pageStore.name !== null && pageStore.name && routePages[pageStore.name].hasHeader;

Expand All @@ -69,17 +50,19 @@ export const AppRouteContainer = observer<AppRouteContainerProps>(function AppRo
return <WeChatRedirect />;
}

const Page = lazyPages[name];
if (!Page) {
console.error(`Page not found: ${name}`);
return <Redirect to="/" />;
}

return (
<FlatThemeBodyProvider prefersColorScheme={preferencesStore.prefersColorScheme}>
<AppRouteErrorBoundary
Comp={
componentCache.get(name) ||
loadable(Comp, {
fallback: <LoadingPage hasHeader={hasHeader} />,
})
}
{...{ title, routeProps }}
/>
<AppRouteErrorBoundary>
<Suspense fallback={<LoadingPage hasHeader={hasHeader} />}>
<Page {...routeProps} />
</Suspense>
</AppRouteErrorBoundary>
</FlatThemeBodyProvider>
);
});
20 changes: 4 additions & 16 deletions packages/flat-pages/src/AppRoutes/AppRouteErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
import React, { ComponentType } from "react";
import { RouteComponentProps } from "react-router-dom";
import React from "react";
import { ErrorPage } from "flat-components";
import { FlatServices } from "@netless/flat-services";

export interface AppRouteErrorBoundaryProps {
Comp: ComponentType<any>;
title: string;
routeProps: RouteComponentProps;
}

export interface AppRouteErrorBoundaryState {
hasError: boolean;
}

export class AppRouteErrorBoundary extends React.PureComponent<
AppRouteErrorBoundaryProps,
AppRouteErrorBoundaryState
> {
public constructor(props: AppRouteErrorBoundaryProps) {
export class AppRouteErrorBoundary extends React.PureComponent<{}, AppRouteErrorBoundaryState> {
public constructor(props: {}) {
super(props);
this.state = { hasError: false };
}
Expand All @@ -36,8 +26,6 @@ export class AppRouteErrorBoundary extends React.PureComponent<
return <ErrorPage />;
}

const { Comp, routeProps } = this.props;

return React.createElement(Comp, routeProps);
return this.props.children;
}
}
3 changes: 1 addition & 2 deletions packages/flat-pages/src/AppRoutes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const AppRoutes: React.FC = () => {
<Switch>
{Object.keys(routeConfig).map(((name: keyof RouteConfig) => {
const { path } = routeConfig[name];
const { component, title } = routePages[name];
const { title } = routePages[name];
return (
<Route
key={name}
Expand All @@ -24,7 +24,6 @@ export const AppRoutes: React.FC = () => {
return (
<AppRouteContainer
key={routeProps.location.pathname}
Comp={component}
name={name}
routeProps={routeProps}
title={title}
Expand Down
6 changes: 4 additions & 2 deletions packages/flat-stores/src/whiteboard-store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,12 @@ export class WhiteboardStore {
return;
}

if (file.resourceType !== FileResourceType.Directory) {
void message.info(FlatI18n.t("inserting-courseware-tips"));
if (file.resourceType === FileResourceType.Directory) {
return;
}

void message.info(FlatI18n.t("inserting-courseware-tips"));

const fileService = await FlatServices.getInstance().requestService("file");
if (!fileService) {
void message.error(FlatI18n.t("unable-to-insert-courseware"));
Expand Down