0

我有一个已翻译成多种语言的反应应用程序,并且还包含一些日期格式化功能。例如,我想允许用户在 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例如查询字符串会触发它,以便我可以设置这些设置?

4

3 回答 3

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 等),维护起来很快就会变得很麻烦。

于 2021-05-31T13:11:34.703 回答
0

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

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
  }
}
于 2022-01-20T09:58:15.640 回答
0

对于第一个检测到的语言,您可能需要尝试onInitialized 事件。然后根据您的需要检查i18next.languagei18next.languages 。

编辑:因为 v21.0.0 还有i18next.resolvedLanguage

于 2021-06-01T19:52:57.803 回答