First of all thanks for the effort in creating and maintaining this module, it works like a charm.
But, there's something crucial (imo) I'm missing and that is a function or some way to let the user set the language to their choice (given the supported languages the app would provide).
(I tried requiring the new translations in 'i18n.translations = ....' but it only works for some of the screens.. I believe this is because the screens (and their translations) have to be re-rendered?)
Is this something that could be added or is it not feasible?
+1!
I believe you can achieve what you want by changing the locale at runtime
For instances, by using the example translations in the documentation:
I18n.locale = 'en';
console.log(I18n.t('greeting'));
I18n.locale = 'fr';
console.log(I18n.t('greeting'));
Displays on the logs:
11-16 10:34:46.432 31325 9705 I ReactNativeJS: Hi!
11-16 10:34:46.432 31325 9705 I ReactNativeJS: Bonjour!
Also, as displayed in the documentation of I18n, you can also call the t method passing the locale: I18n.t("some.scoped.translation", {locale: "fr"});
I believe this is because the screens (and their translations) have to be re-rendered?)
Absolutely, you need to re-render the screen. One solution might be to tie this lib with a Redux store (if you're using it), so that it will automatically re-render the screens when needed :)
Also, thanks @jeromegrosse
Closing, feel free to re-open :)
you can use this library https://github.com/MaxToyberman/react-native-locale-listener to detect changes in your locale and then reload your app.
Fyi: I created a tutorial and a sample on how to successfully implement multi language support, also as a user-defined setting, with this plugin and redux (and the new React Navigation). (Currently the sample uses no redux for navigation, but i'm hoping to add that soon as I think that it would work even better.)
I am trying to change language of my app in run time when user selects the language. I am trying to do like this
import I18n from 'react-native-i18n'
onChangeLanguage = () => {
console.log('String before change : >>> ', I18n.t('welcome'))
I18n.locale = 'hi'
console.log('String after change : >>> ', I18n.t('welcome'))
}
In Both logs I got same string . If the language is changed how to re render component to reflect the language changes.
you can add a function to config file like this
export function L(key) {
let word=I18n.t(key,{locale: I18n.local})
return word
}
and call it like that
`import {L} from './config'
title={L('listType')}/>`
Thanks @jeromegrosse !
my code in i18n.js:
import I18n from 'react-native-i18n';
import en from './en';
import zh_Hans from './zh-Hans';
import zh_Hant from './zh-Hant';
I18n.fallbacks = true;
I18n.translations = {
en,
zh_Hans,
zh_Hant
};
I18n.langs = [
'en',
'zh_Hans',
'zh_Hant'
];
I18n.switchLanguage = () => {
const index = I18n.langs.indexOf(I18n.locale);
if (index === I18n.langs.length - 1)
I18n.locale = I18n.langs[0];
else
I18n.locale = I18n.langs[index + 1];
};
export default I18n;
If you don't use redux for refresh component when language was changed, you can use:
// i18n.js
export const strings = (name, params = {}) => I18n.t(name, params);
export const switchLanguage = (lang, component) => {
I18n.locale = lang;
component.forceUpdate();
};
// Component
import { strings, switchLanguage } from 'path to i18n.js';
onSetRuLang = () => {
switchLanguage('ru', this);
};
// render
<Text>{strings('login_to_account')}</Text>
<Button label="RU" onPress={this.onSetRuLang} />
Need refresh only current components, other component get actual language when will render.
Thanks a lot @AndreyPatseiko . Works like a charm
If you don't use redux for refresh component when language was changed, you can use:
// i18n.js export const strings = (name, params = {}) => I18n.t(name, params); export const switchLanguage = (lang, component) => { I18n.locale = lang; component.forceUpdate(); }; // Component import { strings, switchLanguage } from 'path to i18n.js'; onSetRuLang = () => { switchLanguage('ru', this); }; // render <Text>{strings('login_to_account')}</Text> <Button label="RU" onPress={this.onSetRuLang} />Need refresh only current components, other component get actual language when will render.
Thank you very much, you saved my life.
If you don't use redux for refresh component when language was changed, you can use:
// i18n.js export const strings = (name, params = {}) => I18n.t(name, params); export const switchLanguage = (lang, component) => { I18n.locale = lang; component.forceUpdate(); }; // Component import { strings, switchLanguage } from 'path to i18n.js'; onSetRuLang = () => { switchLanguage('ru', this); }; // render <Text>{strings('login_to_account')}</Text> <Button label="RU" onPress={this.onSetRuLang} />Need refresh only current components, other component get actual language when will render.
this solution doesn't work if we go back to previous screen after switching language. The previous page in the navigator stack will not render
Most helpful comment
I believe you can achieve what you want by changing the locale at runtime
For instances, by using the example translations in the documentation:
Displays on the logs: