Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using react i18next on all nested components

I have a question regarding the multi-language support for complex React application. All examples and documentation are based on "flat" application without nested/child components.

How to approach data nested like this:

<i18n>
    <App>
        translate('base')(
          <Base>
              <Child1 />
              <Child2 />
              {t('Hello')}
          </Base>
        )
    </App>
</i18n>

Should I wrap every child component with translate HOC?
Is there some other way to pass the translation function down to the child components?

like image 201
J33nn Avatar asked Aug 01 '18 10:08

J33nn


People also ask

What is the difference between i18n and i18next?

i18next is an i18n framework written in and for JavaScript. It provides the standard i18n features of interpolation, formatting, and handling plurals and context. A 30,000 foot view of i18next would be that it provides a function that takes a key, some options, and returns the value for the current language.

How is useTranslation used in functions?

You can fix it by moving the useTranslation hook to the MyNav component body and pass the translation function t as a closure in getMyMenu . import { useTranslation } from "react-i18next"; export const MyNav = props => { const { t } = useTranslation('translations'); function getMyMenu(a) { if (a.

Can I use React i18next in Nextjs?

Next. js has supported i18n since v10. 0.0, it allows us to set the default language, the current language in use, and the supported languages. To set locales in a Next.


3 Answers

I had the same problem not long ago. There are 4 solutions I found for this.

  1. Passing t down to every component. This one is very annoying and leads to a lot of bugs because I was forgetting to pass it down all the time.

  2. Using the NamespacesConsumer context provided by react-i18next. This one is also really annoying and the syntax is sometimes too weird and repetitive. This can also be bad for performance because components might re-render often.

  3. Using the withNamespaces HOC provided by react-i18next, this is a great option, it's easy to read and doesn't pollute your code with translation syntax. It's also more efficient than the previous two options.

  4. This one is my favorite solution, I end up using i18next directly because you have access to t() everywhere out of the box, without additional code.

If you want to keep react-i18next, I would recommend you to use a HOC, it's way easier to debug, test and develop. But honestly, i18next is doing a better job in my own opinion. I initially use react-i18next because I thought it was the react way to go, but it is just a pain to use it, react-i18next has a lot of bugs and it's way more code to write. Using i18next is simple as this

import i18next from 'i18next';

i18next.t('parentKey.childKey');
like image 70
Vincent D'amour Avatar answered Sep 22 '22 15:09

Vincent D'amour


The best approach would be to wrap your main component with a React.Context and pass the t prop as a context and have it accessible in each of your nested child components.

I am using localization as well in my application like this.

Pros:

  • Doesn't destroy child hierarchy when every component is wrapped with a hOC
  • In the future if you decide to chose another library for localization, you can just change the main Provider component of that Context and it will update the implementation through out your application.
  • Since the translations are loaded initially, your context won't update & re-render issue won't come again and again.
like image 26
Adeel Imran Avatar answered Sep 23 '22 15:09

Adeel Imran


If you are using hooks, and not classes (like me) when coding your React components, then you can use the useTranslation hook:

import React from 'react';
import { useTranslation } from 'react-i18next';

export function MyComponent() {
  const { t, i18n } = useTranslation();
  // or const [t, i18n] = useTranslation();

  return <p>{t('my translated text')}</p>
}

This, just like the withTranslation wrapper, requires importing (the hook) in every file which uses translations.

like image 20
vsync Avatar answered Sep 23 '22 15:09

vsync