我可以使用 i18next-browser-languageDetector 检测首次检测到语言的时间吗?
Can I detect when a language is detected for the first time using i18next-browser-languageDetector?
我有一个反应应用程序,我已经翻译成多种语言,并且还包含一些日期格式化功能。例如,我想允许用户在 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
的查询字符串会触发它,以便我可以设置这些设置?
我设法解决了这个问题,方法是首先检查本地存储中是否保存了一种语言,将其添加到 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 等
对于第一个检测到的语言,您可能想尝试 onInitialized event。
然后根据需要勾选i18next.language or i18next.languages。
编辑:从 v21.0.0 开始还有 i18next.resolvedLanguage
非常感谢我在第一次渲染访问时遇到了问题,因为 i18n.language 是“es-ES”或“en-EN”并将其保存在本地存储中...
我用 switch 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
}
}
我有一个反应应用程序,我已经翻译成多种语言,并且还包含一些日期格式化功能。例如,我想允许用户在 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
的查询字符串会触发它,以便我可以设置这些设置?
我设法解决了这个问题,方法是首先检查本地存储中是否保存了一种语言,将其添加到 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 等
对于第一个检测到的语言,您可能想尝试 onInitialized event。 然后根据需要勾选i18next.language or i18next.languages。
编辑:从 v21.0.0 开始还有 i18next.resolvedLanguage
非常感谢我在第一次渲染访问时遇到了问题,因为 i18n.language 是“es-ES”或“en-EN”并将其保存在本地存储中... 我用 switch 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
}
}