【问题标题】:Can I detect when a language is detected for the first time using i18next-browser-languageDetector?我可以使用 i18next-browser-languageDetector 检测第一次检测到语言的时间吗?
【发布时间】:2022-01-20 18:28:09
【问题描述】:

我有一个已翻译成多种语言的 react 应用程序,还包含一些日期格式化功能。例如,我想允许用户在 12 小时和 24 小时之间进行更改,但是当切换到德语时,会自动将该选项更改为 24 小时(因为德国通常不使用 12 小时时间)。

我仍然希望用户能够更改此选项,并且我也不希望每次重新加载页面时将其重置为 24 小时。

我正在使用i18nexti18next-browser-languageDetector 来检测浏览器语言,目前我有一个绑定到i18next 的事件,用于用户手动更改语言时,以便根据每个用户设置这些默认设置语言,而且效果很好:

i18n.on('languageChanged', lang => {
  // Language specific options
  if (lang === 'de') {
    store.setTimeFormat('24h');
  }
  if (lang === 'en') {
    store.setTimeFormat('12h');
  }
});

现在,唯一的问题是在首次加载应用时,即浏览器检测器首次检测到用户的语言时,不会触发此功能。

如何确定i18next-browser-languageDetector最初检测到语言的时间,即不是从本地存储加载,而是例如lng=de的查询字符串会触发它,以便我可以设置这些设置?

【问题讨论】:

    标签: reactjs i18next react-i18next i18next-browser-languagedetector


    【解决方案1】:

    我设法解决了这个问题,首先检查一种语言是否已保存在本地存储中,将其添加到 i18next 选项对象中,然后我可以稍后检查它以设置默认值。

    import i18n from 'i18next';
    import { initReactI18next } from 'react-i18next';
    import LanguageDetector from 'i18next-browser-languagedetector';
    import Backend from 'i18next-http-backend';
    
    // Check the localstorage before i18next can
    const storedLang = localStorage.getItem('i18nextLng');
    
    i18n
      .use(LanguageDetector)
      .use(Backend)
      .use(initReactI18next)
      .init({
        fallbackLng: 'en',
        interpolation: {
          escapeValue: false,
        },
        backend: {
          loadPath: '/i18n/{{lng}}/{{ns}}.json',
        },
        storedLang, // Add it here
      });
    
    export default i18n;
    

    然后在我的组件中,我可以将以下内容放入函数中:

    import { useTranslation } from 'react-i18next';
    import { mySettingsStore } from 'stores';
    
    const setDefaults = (lang, store) => {
      // Language specific options
      if (lang === 'de') {
        store.setTimeFormat('24h');
      }
      if (lang === 'en') {
        store.setTimeFormat('12h');
      }
      // etc...
    };
    
    const Component = () => {
      const store = mySettingsStore(); // zustand store
      const { i18n } = useTranslation();
    
      // If localstorage was empty: no language set
      if (!i18n.options.storedLang) {
        setDefaults(i18n.language, store);
        i18n.options.storedLang = i18n.language;
      }
    
      // Language changed manually
      i18n.on('languageChanged', lang => {
        setDefaults(lang, store);
      });
    
      return (...);
    };
    
    export default Component;
    

    但是,如果通过查询字符串设置语言,则此方法不会更新选项,例如https://my.app?lng=de,如果本地存储中已设置语言。这也可以通过以相同方式检查查询字符串参数来解决,但如果使用更多选项,维护起来很快就会变得很麻烦,例如会话存储、cookie 等。

    【讨论】:

      【解决方案2】:

      非常感谢,我在第一次渲染访问时遇到了问题,因为 i18n.language 是“es-ES”或“en-EN”,并将其保存在本地存储中... 我用一个 swtich case 解决了它:

      if (!i18n.options.storedLang) {
          switch(i18n.language){
             case "es-ES":
               setDefaults("es", store)
               i18n.options.storedLang = "es"
               //and this for other uses, for example vars to use in <ReactCountryFlag countryCode={"GB"} svg />
               break
            case: "en-EN":
               setDefault("en",store)
               i18n.options.storedLang = "es"
               //and this for other uses, for example vars to use in <ReactCountryFlag countryCode={"ES"} svg />
               break
            default: break
        }
      }
      

      【讨论】:

      【解决方案3】:

      对于第一个检测到的语言,您可能想尝试onInitialized event。 然后检查i18next.languagei18next.languages,取决于你的需要。

      编辑:从 v21.0.0 开始还有i18next.resolvedLanguage

      【讨论】:

      • 问题是这个事件无法判断一个语言是否已经被i18next-browser-languagedetector插件保存在localstorage、session或cookie等中。
      猜你喜欢
      • 2019-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 1970-01-01
      • 2016-09-28
      相关资源
      最近更新 更多