我应该如何在React组件库中处理国际化?

时间:2019-04-30 15:45:39

标签: javascript reactjs internationalization

我可以在React应用程序中找到很多有关如何进行国际化的示例,但对于组件库却找不到。

我正在使用短语应用,我想知道是否有人对如何以一种好的方式提出建议。

  1. 所有组件均以道具形式使用应使用的语言
  2. 所有翻译均以短语应用
  3. 这是我工作的公司的组件库,因此该库将具有需要翻译的默认标签

我认为的选项:

  • 在阿波罗客户端商店中加载当前语言的键/值,并创建一个帮助程序以获取给定键的值
  • 尝试使用这样的库:https://github.com/phrase/react-intl-phraseapp,但我不知道它是否有效,因为它不是SPA

1 个答案:

答案 0 :(得分:1)

所以我们最终最终使用了react-intl,导出了包装在IntlProvider中的每个组件以及所需的语言环境和消息。 IntlProvider的配置是在构造函数中以组件状态设置的:

    this.state = {
       i18nCfg: IntlUtils.init(props.language, 'SignOutMenu')
    }

...,然后在组件的render()中进行设置:

    render() {
      const { i18nCfg } = this.state;
      return (
         <IntlProvider locale={i18nCfg.language} messages={i18nCfg.messages}>

...

语言环境可以由injectIntl HOC给出的父组件提供。

<SignOutMenu language={this.props.intl.locale}/>

,或者如果未定义语言,则在getUserLanguage()上使用util方法init()从浏览器中检测到。

您只需要小心,以防止在应用程序中重复出现消息ID,因此,我使用名称空间字符串初始化了该组件,该字符串表示仅与给定组件相关的消息(在getMessages()中完成):< / p>


    import {addLocaleData} from 'react-intl';
    import en from 'react-intl/locale-data/en';
    import de from 'react-intl/locale-data/de';
    import messagesEn from '../locales/lang/i18n_en.json';
    import messagesDe from '../locales/lang/i18n_de.json';

    const defaultLanguage = 'en';
    const supportedLanguages = ['en', 'de'];

    export default class IntlUtils {

       static init = (language, namespace) => {
          // add the supported locale data
          addLocaleData([...en, ...de]);

          // get supported language
          const lang = language && supportedLanguages.indexOf(language) > -1 ? language : IntlUtils.getUserLanguage();

          // return back data for IntlProvider
          return {
             language: lang,
             messages: IntlUtils.getMessages(lang, namespace)
          }
       }

       static getMessages = (language, namespace) => {
          let langMsgs;
          switch (language) {
             case 'de': langMsgs = messagesDe; break;

             case 'en':
             default: langMsgs = messagesEn;
          }

          if (langMsgs) {
             const matchNS = namespace + ".";
             const filtered = {};
             for (var key in langMsgs) {
                if (key.startsWith(matchNS)) {
                   filtered[key] = langMsgs[key];
                }
             }
             return filtered;
          }
       }

       static getUserLanguage = () => {
          //if none available, take it from browser
          const browserLanguage = window.navigator.userLanguage || window.navigator.language;
          if (browserLanguage) {
             // get the language code and store it in local prefs for nexttime
             const m = browserLanguage.match(/^([a-z]+)/i);
             if (m) {
                return m[0];
             }
          }
          // nothing found -> return default en
          return defaultLanguage;
       }
    }

为了能够在IntlUtil中导入json文件,我必须安装“ babel-plugin-inline-json-import”的devDependency并将其添加到.babelrc文件中:

   "plugins": [
      ["inline-json-import", {}]
   ]

我还发现,将injectIntl​​ HOC与方法formatMessage()一起使用不能在初始化IntlProvider的同一组件中正常工作,因为IntlProvider是IntlProvider实例的HOC,并带有来自上述组件的消息。)

请注意,我们的语言切换机制涉及页面的刷新,因此它与init()一样具有吸引力。但是我不能说当您在不刷新页面的情况下切换语言时,使用上下文或redux时效果如何。但是我们很快将在一个这样的应用程序中使用它,所以我可以在此处发布更新...

希望这可以至少在某种程度上帮助您和其他人