UNPKG

1.91 kBJavaScriptView Raw
1/* @flow */
2import React from 'react';
3import { EventEmitter } from 'fbemitter';
4import NativeAppLoading from './AppLoadingNativeWrapper';
5
6type Props =
7 | {
8 startAsync: () => Promise<any>,
9 onError?: (error: Error) => void,
10 onFinish: () => void,
11 }
12 | {
13 startAsync: null,
14 onError: null,
15 onFinish: null,
16 };
17
18export default class AppLoading extends React.Component<Props> {
19 _isMounted: boolean;
20
21 componentDidMount() {
22 this._isMounted = true;
23 _emitEvent('componentDidMount');
24
25 // startAsync is optional, you can do this process manually if you prefer
26 // (this is mainly for backwards compatibility and it is not recommended)
27 if (this.props.startAsync) {
28 /* $FlowFixMe */
29 this._startLoadingAppResourcesAsync().done();
30 }
31 }
32
33 componentWillUnmount() {
34 this._isMounted = false;
35 _emitEvent('componentWillUnmount');
36 }
37
38 _startLoadingAppResourcesAsync = async () => {
39 if (!this.props.onFinish) {
40 throw new Error(
41 'AppLoading onFinish prop is required if startAsync is provided'
42 );
43 }
44
45 try {
46 await this.props.startAsync();
47 } catch (e) {
48 if (!this._isMounted) return;
49
50 if (this.props.onError) {
51 this.props.onError(e);
52 } else {
53 throw e;
54 }
55 } finally {
56 if (!this._isMounted) return;
57
58 // If we get to this point then we know that either there
59 // was no error, or the error was handled.
60 if (this.props.onFinish) {
61 this.props.onFinish();
62 }
63 }
64 };
65
66 render() {
67 return <NativeAppLoading />;
68 }
69}
70
71let _lifecycleEmitter: ?EventEmitter;
72function _emitEvent(event: string) {
73 if (_lifecycleEmitter) {
74 _lifecycleEmitter.emit(event);
75 }
76}
77
78export function getAppLoadingLifecycleEmitter() {
79 if (!_lifecycleEmitter) {
80 _lifecycleEmitter = new EventEmitter();
81 }
82 return _lifecycleEmitter;
83}
84
\No newline at end of file