Skip to content

Commit

Permalink
feat: renderClient with callback (#4979)
Browse files Browse the repository at this point in the history
  • Loading branch information
ycjcl868 committed Jul 27, 2020
1 parent bfc2c9f commit 677cd21
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 7 deletions.
32 changes: 30 additions & 2 deletions packages/renderer-mpa/src/renderClient/renderClient.test.tsx
@@ -1,7 +1,22 @@
import React from 'react';
import { cleanup, render } from '@testing-library/react';
import { Plugin } from '@umijs/runtime';
import React from 'react';
import { act } from 'react-dom/test-utils';
import { renderClient } from './renderClient';
import { render } from '@testing-library/react';

let container: HTMLDivElement;
beforeEach(() => {
container = document.createElement('div');
container.id = 'app';
document.body.appendChild(container);
});

afterEach(() => {
document.body.removeChild(container);
// @ts-ignore
container = null;
cleanup();
});

test('normal', () => {
const plugin = new Plugin({
Expand Down Expand Up @@ -60,6 +75,19 @@ test('normal', () => {
path: '/haha',
});
}).toThrow(/Render failed, route of path \/haha not found\./);

let loading = true;
act(() => {
renderClient({
plugin,
routes,
rootElement: 'app',
callback: () => {
loading = false;
},
});
});
expect(loading).toBeFalsy();
});

test('do not support child routes', () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/renderer-mpa/src/renderClient/renderClient.tsx
Expand Up @@ -9,6 +9,7 @@ interface IOpts {
defaultTitle?: string;
rootElement?: string | HTMLElement;
path?: string;
callback?: () => void;
}

function getRootContainer(opts: { routes: any[]; path: string }) {
Expand Down Expand Up @@ -61,10 +62,12 @@ export function renderClient(opts: IOpts): any {
typeof opts.rootElement === 'string'
? document.getElementById(opts.rootElement)
: opts.rootElement;
const callback = opts.callback || (() => {});
// @ts-ignore
ReactDOM[window.g_useSSR ? 'hydrate' : 'render'](
rootContainer,
rootElement,
callback,
);
} else {
return rootContainer;
Expand Down
66 changes: 65 additions & 1 deletion packages/renderer-react/src/renderClient/renderClient.test.tsx
@@ -1,9 +1,21 @@
import React from 'react';
import { render, cleanup, waitFor, getByText } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { createMemoryHistory, Plugin, dynamic } from '@umijs/runtime';
import renderClient, { preloadComponent } from './renderClient';

afterEach(cleanup);
let container;
beforeEach(() => {
container = document.createElement('div');
container.id = 'app';
document.body.appendChild(container);
});

afterEach(() => {
document.body.removeChild(container);
container = null;
cleanup();
});

test('normal', async () => {
const history = createMemoryHistory({
Expand Down Expand Up @@ -49,6 +61,58 @@ test('normal', async () => {
expect(routeChanges).toEqual(['POP /foo', 'PUSH /bar']);
});

test('normal with mount', async () => {
const history = createMemoryHistory({
initialEntries: ['/foo'],
});
const routeChanges: string[] = [];
const plugin = new Plugin({
validKeys: ['onRouteChange', 'rootContainer'],
});
plugin.register({
apply: {
onRouteChange({ location, action }: any) {
routeChanges.push(`${action} ${location.pathname}`);
},
rootContainer(container: any, args: any) {
if (!(args.history && args.plugin && args.routes)) {
throw new Error(
'history, plugin or routes not exists in the args of rootContainer',
);
}
return <div>{container}</div>;
},
},
path: '/foo',
});
let loading = true;
act(() => {
renderClient({
history,
plugin,
// #app
rootElement: 'app',
routes: [
{ path: '/foo', component: () => <h1>foo</h1> },
{ path: '/bar', component: () => <h1>bar</h1> },
],
callback: () => {
loading = false;
},
});
});
expect(container.outerHTML).toEqual(
'<div id="app"><div><h1>foo</h1></div></div>',
);
expect(loading).toBeFalsy();

history.push({
pathname: '/bar',
});
expect(container.innerHTML).toEqual('<div><h1>bar</h1></div>');
expect(routeChanges).toEqual(['POP /foo', 'PUSH /bar']);
});

const Common = ({ title }) => {
return <h1>{title}</h1>;
};
Expand Down
11 changes: 7 additions & 4 deletions packages/renderer-react/src/renderClient/renderClient.tsx
Expand Up @@ -17,6 +17,7 @@ interface IRouterComponentProps {

interface IOpts extends IRouterComponentProps {
rootElement?: string | HTMLElement;
callback?: () => void;
}

function RouterComponent(props: IRouterComponentProps) {
Expand Down Expand Up @@ -111,19 +112,21 @@ export default function renderClient(opts: IOpts) {
typeof opts.rootElement === 'string'
? document.getElementById(opts.rootElement)
: opts.rootElement;
// flag showing SSR successed
const callback = opts.callback || (() => {});

// flag showing SSR successed
if (window.g_useSSR) {
if (opts.dynamicImport) {
// dynamicImport should preload current route component
// first loades);
preloadComponent(opts.routes).then(function () {
ReactDOM.hydrate(rootContainer, rootElement);
ReactDOM.hydrate(rootContainer, rootElement, callback);
});
} else {
ReactDOM.hydrate(rootContainer, rootElement);
ReactDOM.hydrate(rootContainer, rootElement, callback);
}
} else {
ReactDOM.render(rootContainer, rootElement);
ReactDOM.render(rootContainer, rootElement, callback);
}
} else {
return rootContainer;
Expand Down

0 comments on commit 677cd21

Please sign in to comment.