首页 > 解决方案 > 使用 async/await 在 addLocaleData 上动态导入语言环境

问题描述

我有一个“外部”国际提供者,因为我必须处理一些反应组件之外的标签。我正在尝试在不使用 require 语句的情况下动态加载语言环境,但我遇到了一个问题,我不确定它为什么会发生。因此,以下代码有效:

//intlProvider.js
import { IntlProvider, addLocaleData } from 'react-intl';
import Locale from '../../../../utils/locale';

const locale = Locale.getLocale();
addLocaleData(require(`react-intl/locale-data/${locale}`));
const messages = Locale.getMessages('prot');
const intlProvider = new IntlProvider({ locale, messages });
const { intl } = intlProvider.getChildContext();

export default intl;

然后我在 sharedMessages.js 文件中读取了 intl:

import { defineMessages } from 'react-intl';
import intl from '../components/i18n/Intl';

const messages = defineMessages({
  interest: {
    id: 'sharedMessages.rate.label',
    defaultMessage: 'Interest',
  },
  bank: {
    id: 'sharedMessages.bank.label',
    defaultMessage: 'Bank',
  },
});
function prepareSharedMessages() {
  const msgsObj = {};
  Object.keys(messages).forEach(item => {
    msgsObj[item] = intl.formatMessage(messages[item]);
  });
  return msgsObj;
}
const sharedMessages = prepareSharedMessages();

export default sharedMessages;

上面的代码工作正常,但是因为我想摆脱这一行中的 require 语句(因为动态导入会大大增加捆绑包):

addLocaleData(require(`react-intl/locale-data/${locale}`));

我试图将其替换为:

(async localeCode => {
  const localeData = await import(`react-intl/locale-data/${localeCode}`);
  addLocaleData(localeData.default);
})(locale);

预期的行为 我希望语言环境能够正确加载,但显然应用程序正试图在它应该之前获取它。由于我使用的是async/await,因此我希望在应用程序的其余部分尝试使用它之前设置它。(如果它在反应组件内部,我可以使用componentDidMount来触发语言环境,但是我怎样才能为非反应组件实现这种行为?)

当前行为 替换上述 import 语句的 require 后,我收到 react-intl 警告:

[React Intl] 缺少语言环境数据:“de”。使用默认语言环境:“en”作为后备。

我的环境:

操作系统: macOS Mojave 10.14

浏览器版本: Chrome 71.0.3578.98(官方版本)(64 位)

标签: javascriptreactjsecmascript-6promisereact-intl

解决方案


推荐阅读