优化 loadRenderer 逻辑,减少返回约束

This commit is contained in:
liaoxuezhi 2019-05-19 18:08:11 +08:00
parent 27c2bc721e
commit 3a0c332cde
4 changed files with 81 additions and 25 deletions

View File

@ -1,6 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`factory custom loadRenderer 1`] = `
exports[`factory custom not found 2! 1`] = `
<div>
<div>
Not Found
</div>
</div>
`;
exports[`factory custom not found 3! 1`] = `
<div>
<div>
Not Found
</div>
</div>
`;
exports[`factory custom not found! 1`] = `
<div>
<div>
Not Found

View File

@ -19,7 +19,7 @@ test('factory unregistered Renderer', async () => {
expect(container).toMatchSnapshot(); // not found
});
test('factory custom loadRenderer', async () => {
test('factory custom not found!', async () => {
const {
container,
} = render(amisRender({
@ -32,6 +32,32 @@ test('factory custom loadRenderer', async () => {
expect(container).toMatchSnapshot(); // not found
});
test('factory custom not found 2!', async () => {
const {
container,
} = render(amisRender({
type: 'my-renderer',
a: 23
}, {}, makeEnv({
loadRenderer: () => () => (<div>Not Found</div>)
})));
await wait(100);
expect(container).toMatchSnapshot(); // not found
});
test('factory custom not found 3!', async () => {
const {
container,
} = render(amisRender({
type: 'my-renderer',
a: 23
}, {}, makeEnv({
loadRenderer: () => (<div>Not Found</div>)
})));
await wait(100);
expect(container).toMatchSnapshot(); // not found
});
test('factory load Renderer on need', async () => {
const {
container,
@ -55,16 +81,9 @@ test('factory load Renderer on need', async () => {
component: MyComponent,
test: /\bmy-renderer2$/
});
return Promise.resolve(({
retry
}) => {
retry();
return null;
})
}
})));
await wait(200);
await wait(100);
expect(container).toMatchSnapshot(); // not found
});

View File

@ -29,6 +29,7 @@ export default class LazyComponent extends React.Component<LazyComponentProps, L
partialVisibility: true,
};
mounted:boolean = false;
constructor(props: LazyComponentProps) {
super(props);
@ -40,6 +41,14 @@ export default class LazyComponent extends React.Component<LazyComponentProps, L
};
}
componentWillMount() {
this.mounted = true;
}
componentWillUnmount() {
this.mounted = false;
}
handleVisibleChange(visible: boolean) {
this.setState({
visible: visible,
@ -52,12 +61,12 @@ export default class LazyComponent extends React.Component<LazyComponentProps, L
this.props
.getComponent()
.then(component =>
this.setState({
this.mounted && typeof component === 'function' && this.setState({
component: component,
})
)
.catch(reason =>
this.setState({
this.mounted && this.setState({
component: () => <div className="alert alert-danger">{String(reason)}</div>,
})
);

View File

@ -9,7 +9,7 @@ import {
getEnv
} from 'mobx-state-tree';
import {
Location
Location, parsePath
} from 'history';
import {
wrapFetcher
@ -80,7 +80,7 @@ export interface RendererEnv {
affixOffsetTop: number;
affixOffsetBottom: number;
richTextToken: string;
loadRenderer: (schema:Schema, path:string) => Promise<React.ReactType>;
loadRenderer: (schema:Schema, path:string, reRender:Function) => Promise<React.ReactType> | React.ReactType | JSX.Element | void;
[propName:string]: any;
};
@ -134,7 +134,7 @@ export interface RenderOptions {
rendererResolver?: (path:string, schema:Schema, props:any) => null | RendererConfig;
copy?: (contents:string) => void;
getModalContainer?: () => HTMLElement;
loadRenderer?: (schema:Schema, path: string) => Promise<React.ReactType>;
loadRenderer?: (schema:Schema, path: string, reRender:Function) => Promise<React.ReactType> | React.ReactType | JSX.Element | void;
affixOffsetTop?: number;
affixOffsetBottom?: number;
richTextToken?: string;
@ -434,7 +434,17 @@ class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
return (
<LazyComponent
{...rest}
getComponent={() => rest.env.loadRenderer(schema, $path)}
getComponent={async () => {
const result = await rest.env.loadRenderer(schema, $path, this.reRender);
if (result && typeof result === "function") {
return result;
} else if (result && React.isValidElement(result)) {
return () => result;
}
this.reRender();
return () => loadRenderer(schema, $path)
}}
$path={$path}
retry={this.reRender}
/>
@ -626,20 +636,22 @@ export function HocStoreFactory(renderer:{
}
function loadRenderer(schema:Schema, path:string) {
return (
<Alert level="danger">
<p>Error: </p>
<p>Path: {path}</p>
<pre><code>{JSON.stringify(schema, null, 2)}</code></pre>
</Alert>
);
}
const defaultOptions:RenderOptions = {
session: 'global',
affixOffsetTop: 50,
affixOffsetBottom: 0,
richTextToken: '',
loadRenderer(schema, path) {
return Promise.resolve(() => (
<Alert level="danger">
<p>Error: </p>
<p>Path: {path}</p>
<pre><code>{JSON.stringify(schema, null, 2)}</code></pre>
</Alert>
));
},
loadRenderer,
fetcher() {
return Promise.reject('fetcher is required');
},