-
Notifications
You must be signed in to change notification settings - Fork 27
/
async-locale-data.js
87 lines (74 loc) 路 2.35 KB
/
async-locale-data.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import React from 'react';
import PropTypes from 'prop-types';
import { reportErrorToSentry } from '@commercetools-frontend/sentry';
import { extractLanguageTagFromLocale, mergeMessages } from '../utils';
import loadI18n from '../load-i18n';
const getMessagesForLocale = (data, locale) => {
if (!data || !locale) return {};
if (data[locale]) return data[locale];
const fallbackLanguage = extractLanguageTagFromLocale(locale);
return data[fallbackLanguage];
};
class AsyncLocaleData extends React.Component {
static displayName = 'AsyncLocaleData';
static propTypes = {
children: PropTypes.func.isRequired,
// The locale is optional, which indicates that we don't know yet
// which locale data should be loaded.
// This is important in order to avoid loading different locales and
// therefore causing flashing of translated content on subsequent re-renders.
locale: PropTypes.string,
applicationMessages: PropTypes.oneOfType([
PropTypes.func,
PropTypes.object,
]),
};
state = {
isLoading: true,
locale: null,
messages: null,
};
isUnmounting = false;
componentDidMount() {
if (this.props.locale) this.loadLocaleData(this.props.locale);
}
componentDidUpdate(prevProps) {
if (this.props.locale && prevProps.locale !== this.props.locale) {
this.loadLocaleData(this.props.locale);
}
}
componentWillUnmount() {
this.isUnmounting = true;
}
loadLocaleData = async locale => {
let applicationMessagePromise = null;
if (typeof this.props.applicationMessages === 'function') {
applicationMessagePromise = this.props.applicationMessages(locale);
}
const messageFetchingPromises = applicationMessagePromise
? [loadI18n(locale), applicationMessagePromise]
: [loadI18n(locale)];
try {
const [messages, applicationMessages] = await Promise.all(
messageFetchingPromises
);
if (!this.isUnmounting) {
this.setState({
isLoading: false,
locale,
messages: mergeMessages(
messages,
applicationMessages ||
getMessagesForLocale(this.props.applicationMessages, locale)
),
});
}
} catch (error) {
reportErrorToSentry(error, {});
}
};
render() {
return this.props.children(this.state);
}
}
export default AsyncLocaleData;