简体   繁体   中英

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?

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');

You also can pass it down via regular props from outer component.

Like having container components which gets wrapped with translate hoc and the inner components you just pass the t function via props.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM