react-nativereact-navigationreact-i18next

React-Native i18next: Translations are only fired one time


When using react-i18next in my React-Native application everything is working when launching the app. Every tag is translated in the language that has been saved in the application.

When I go to my settings page and update the language for the first time, the whole app changes to the new language. So far so good.

When updating the language a second time, only the settings page gets updated. Other pages don't get triggered to rerender by the "t()" function.

I am using the useTranslations() hook in every page/component in my application and in some other hooks.

if it helps, this is my config:

i18n.js

const resources = {
  en: {
    translation: enTranslation,
  },
  nl: {
    translation: nlTranslation,
  },
  fr: {
    translation: frTranslation,
  },
};

i18n
  .use(RNLanguageDetector)
  .use(initReactI18next) // passes i18n down to react-i18next
  .init({
    debug: true,
    resources,
    compatibilityJSON: 'v3',
    ns: [],
    fallbackLng: 'en',

    supportedLngs: ['en', 'nl', 'fr'],

    keySeparator: false, // we do not use keys in form messages.welcome
    nsSeparator: false, // we do not use keys in form messages.welcome
    namespaceSeparator: false,

    interpolation: {
      escapeValue: false, // react already safes from xss
    },
    returnNull: false,

  });


Solution

  • Ok, issue was a little mistake in listening to events.

    in my language settings, I added a listener for languageChanged in a useFocusEvent:

    useFocusEffect(
    useCallback(() => {
      i18n.on('loaded', languageSetComplete);
    
      i18n.on('languageChanged', languageSetComplete);
    
      return () => {
        i18n.off('loaded');
        i18n.off('languageChanged');
      };
    }, [i18n, languageSetComplete])
    

    I didn't know this also deleted ALL listeners for loaded and languageChanged events in the whole app. So also for the useTranslation hooks.

    See here: https://www.i18next.com/overview/api#events

    enter image description here

    When changing this to

    useFocusEffect(
    useCallback(() => {
      i18n.on('loaded', languageSetComplete);
    
      i18n.on('languageChanged', languageSetComplete);
    
      return () => {
        i18n.off('loaded', languageSetComplete);
        i18n.off('languageChanged', languageSetComplete);
      };
    }, [i18n, languageSetComplete])
    

    everything seems to be working

    Just leaving the question here for someone with the same lack of knowledge as i did.