mirror of
https://github.com/Redocly/redoc.git
synced 2025-01-31 01:54:08 +03:00
feat: pass error in init callback + onLoaded for RedocStandalone
This commit is contained in:
parent
637b493b41
commit
16313b8293
|
@ -11,9 +11,10 @@ export interface RedocStandaloneProps {
|
||||||
spec?: object;
|
spec?: object;
|
||||||
specUrl?: string;
|
specUrl?: string;
|
||||||
options?: RedocRawOptions;
|
options?: RedocRawOptions;
|
||||||
|
onLoaded?: (e?: Error) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RedocStandalone extends React.Component<RedocStandaloneProps> {
|
export class RedocStandalone extends React.PureComponent<RedocStandaloneProps> {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
spec: (props, _, componentName) => {
|
spec: (props, _, componentName) => {
|
||||||
if (!props.spec && !props.specUrl) {
|
if (!props.spec && !props.specUrl) {
|
||||||
|
@ -36,14 +37,14 @@ export class RedocStandalone extends React.Component<RedocStandaloneProps> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { spec, specUrl, options = {} } = this.props;
|
const { spec, specUrl, options = {}, onLoaded } = this.props;
|
||||||
const hideLoading = options.hideLoading !== undefined;
|
const hideLoading = options.hideLoading !== undefined;
|
||||||
|
|
||||||
const normalizedOpts = new RedocNormalizedOptions(options);
|
const normalizedOpts = new RedocNormalizedOptions(options);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<StoreProvider spec={spec} specUrl={specUrl} options={options}>
|
<StoreProvider spec={spec} specUrl={specUrl} options={options} onLoaded={onLoaded}>
|
||||||
{({ loading, store }) =>
|
{({ loading, store }) =>
|
||||||
!loading ? (
|
!loading ? (
|
||||||
<Redoc store={store!} />
|
<Redoc store={store!} />
|
||||||
|
|
|
@ -13,22 +13,27 @@ export interface StoreProviderProps {
|
||||||
|
|
||||||
options?: RedocRawOptions;
|
options?: RedocRawOptions;
|
||||||
|
|
||||||
|
onLoaded?: (e?: Error) => void;
|
||||||
|
|
||||||
children: (props: { loading: boolean; store?: AppStore }) => any;
|
children: (props: { loading: boolean; store?: AppStore }) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StoreProviderState {
|
export interface StoreProviderState {
|
||||||
error?: Error;
|
error?: Error;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
spec?: any;
|
resolvedSpec?: any;
|
||||||
|
prevSpec?: any;
|
||||||
prevSpecUrl?: string;
|
prevSpecUrl?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StoreProvider extends Component<StoreProviderProps, StoreProviderState> {
|
export class StoreProvider extends Component<StoreProviderProps, StoreProviderState> {
|
||||||
static getDerivedStateFromProps(props, state: StoreProviderState) {
|
static getDerivedStateFromProps(nextProps: StoreProviderProps, prevState: StoreProviderState) {
|
||||||
if (props.specUrl !== state.prevSpecUrl) {
|
if (nextProps.specUrl !== prevState.prevSpecUrl || nextProps.spec !== prevState.prevSpec) {
|
||||||
return {
|
return {
|
||||||
spec: null,
|
loading: true,
|
||||||
prevSpecUrl: props.specUrl,
|
resolvedSpec: null,
|
||||||
|
prevSpec: nextProps.spec,
|
||||||
|
prevSpecUrl: nextProps.specUrl,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +42,7 @@ export class StoreProvider extends Component<StoreProviderProps, StoreProviderSt
|
||||||
|
|
||||||
state: StoreProviderState = {
|
state: StoreProviderState = {
|
||||||
loading: true,
|
loading: true,
|
||||||
spec: null,
|
resolvedSpec: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@memoize
|
@memoize
|
||||||
|
@ -53,8 +58,11 @@ export class StoreProvider extends Component<StoreProviderProps, StoreProviderSt
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
if (this.props.spec === null) {
|
if (this.state.resolvedSpec === null) {
|
||||||
this.load();
|
this.load();
|
||||||
|
} else if (!this.state.loading && this.props.onLoaded) {
|
||||||
|
// may run multiple time
|
||||||
|
this.props.onLoaded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +70,11 @@ export class StoreProvider extends Component<StoreProviderProps, StoreProviderSt
|
||||||
const { specUrl, spec, options } = this.props;
|
const { specUrl, spec, options } = this.props;
|
||||||
try {
|
try {
|
||||||
const resolvedSpec = await loadAndBundleSpec(spec || specUrl!);
|
const resolvedSpec = await loadAndBundleSpec(spec || specUrl!);
|
||||||
this.setState({ spec: resolvedSpec, loading: false });
|
this.setState({ resolvedSpec, loading: false });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (this.props.onLoaded) {
|
||||||
|
this.props.onLoaded(e);
|
||||||
|
}
|
||||||
this.setState({ error: e });
|
this.setState({ error: e });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,10 +85,10 @@ export class StoreProvider extends Component<StoreProviderProps, StoreProviderSt
|
||||||
}
|
}
|
||||||
|
|
||||||
const { specUrl, options } = this.props;
|
const { specUrl, options } = this.props;
|
||||||
const { loading, spec } = this.state;
|
const { loading, resolvedSpec } = this.state;
|
||||||
return this.props.children({
|
return this.props.children({
|
||||||
loading,
|
loading,
|
||||||
store: this.makeStore(spec, specUrl, options),
|
store: this.makeStore(resolvedSpec, specUrl, options),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ export function init(
|
||||||
specOrSpecUrl: string | any,
|
specOrSpecUrl: string | any,
|
||||||
options: any = {},
|
options: any = {},
|
||||||
element: Element | null = querySelector('redoc'),
|
element: Element | null = querySelector('redoc'),
|
||||||
callback?: () => void,
|
callback?: (e?: Error) => void,
|
||||||
) {
|
) {
|
||||||
if (element === null) {
|
if (element === null) {
|
||||||
throw new Error('"element" argument is not provided and <redoc> tag is not found on the page');
|
throw new Error('"element" argument is not provided and <redoc> tag is not found on the page');
|
||||||
|
@ -57,13 +57,13 @@ export function init(
|
||||||
RedocStandalone,
|
RedocStandalone,
|
||||||
{
|
{
|
||||||
spec,
|
spec,
|
||||||
|
onLoaded: callback,
|
||||||
specUrl,
|
specUrl,
|
||||||
options: { ...options, ...parseOptionsFromElement(element) },
|
options: { ...options, ...parseOptionsFromElement(element) },
|
||||||
},
|
},
|
||||||
['Loading...'],
|
['Loading...'],
|
||||||
),
|
),
|
||||||
element,
|
element,
|
||||||
callback,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5914,6 +5914,10 @@ mem@^1.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mimic-fn "^1.0.0"
|
mimic-fn "^1.0.0"
|
||||||
|
|
||||||
|
memoize-one@^3.1.1:
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-3.1.1.tgz#ef609811e3bc28970eac2884eece64d167830d17"
|
||||||
|
|
||||||
memory-fs@^0.4.0, memory-fs@~0.4.1:
|
memory-fs@^0.4.0, memory-fs@~0.4.1:
|
||||||
version "0.4.1"
|
version "0.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
|
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user