我有一个react应用程序,我已经将其翻译成几种语言,还包含一些日期格式化功能。例如,我想允许用户在12小时和24小时之间切换,但当切换到德语时,会自动将该选项更改为24小时(因为德国通常不使用12小时(。
我仍然希望这个选项可以由用户更改,我也不希望每次页面重新加载时都将其重置为24小时。
我使用i18next
和i18next-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
的查询字符串会触发它,这样我就可以设置这些设置了?
对于第一种检测到的语言,您可能需要尝试onInitialized事件。然后根据您的需要检查i18next.language或i18next.languages。
edit:由于v21.0.0,还有i18next.resolvedLanguage
我设法解决了这个问题,首先检查一种语言是否保存在本地存储中,并将其添加到i18next-options对象中,然后我可以稍后检查以设置默认值。
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等,则维护起来可能会很快变得麻烦。
非常感谢我在使用i18n的第一次渲染访问中遇到问题。语言是"es es";或";en en";并将其保存在本地存储中。。。我用一个特殊的例子解决了这个问题——雄蕊:
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
}
}