React-native-i18n: Change language

Created on 2 Nov 2016  路  13Comments  路  Source: AlexanderZaytsev/react-native-i18n

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?

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:

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!

All 13 comments

+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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timgcarlson picture timgcarlson  路  5Comments

wyzzy picture wyzzy  路  5Comments

tregismoreira picture tregismoreira  路  7Comments

hannta picture hannta  路  5Comments

mphasize picture mphasize  路  7Comments