Search code examples
reactjstypescriptreact-hooksinternationalizationreact-i18next

How to minimize the number of useTranslation() I must call


I'm currently developing a web application using React and TypeScript. For my app, I have all the texts saved in JSON files under the assets/locales folder, named according to the language used (en.json, jp.json, fr.json). Then, I'm using i18next and initReactI18next in the App.tsx like this:

i18n.use(initReactI18next).init({
  debug: true,
  resources: {
    en: { translation: enJson },
    jp: { translation: jpJson },
    fr: { translation: frJson },
  },
  lng: 'en',
  fallbackLng: false,
  returnEmptyString: false,
  interpolation: {escapeValue: false},
});

and then, from each of my components files, I have useTranslation and useEffect, so I can refer to JSON file for text like this:

<h1>{t('hello-world')}</h1>

instead of writing like:

<h1>Hello World</h1>
import { useTranslation } from 'react-i18next';

const exampleComponent = () => {
  const [t, i18n] = useTranslation();
  const [lang] = useState();

  useEffect(() => {
    i18n.changeLanguage(lang);
  }, [lang, i18n]);
....

But, I have to write useTraslation and useEffect at the top of every component file I use. I feel redundant, and there must be a better way. And it would be great if someone could share their knowledge. Thanks.


Solution

  • That‘s the nature of hooks. Alternatively, you can use a HOC: https://react.i18next.com/latest/withtranslation-hoc

    like here: https://github.com/i18next/react-i18next/blob/master/example/react/src/App.js#L13

    import { withTranslation } from 'react-i18next';
    
    // use hoc for class based components
    class LegacyWelcomeClass extends Component {
      render() {
        const { t } = this.props;
        return <h2>{t('title')}</h2>;
      }
    }
    const Welcome = withTranslation()(LegacyWelcomeClass);