在嵌套组件上使用react-i18next

时间:2018-08-01 10:13:46

标签: reactjs i18next react-i18next

我对复杂的React应用程序的多语言支持有疑问。所有示例和文档均基于无嵌套/子组件的“扁平”应用程序。

如何处理像这样嵌套的数据:

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

我应该用translate HOC包装每个子组件吗?还是有其他方法可以将翻译功能传递给子组件?

4 个答案:

答案 0 :(得分:8)

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 having to code 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');

答案 1 :(得分:3)

您还可以通过外部组件的常规道具将其传递下来。

就像具有被translate hoc包装的容器组件和内部组件一样,您只需通过道具传递t函数即可。

答案 2 :(得分:0)

最好的方法是用React.Context包装您的主要组件,并传递t属性作为上下文,并在每个嵌套的子组件中对其进行访问。

我也在这样的应用程序中使用本地化。

优点:

  • 当每个组件都包裹有hOC时,不会破坏子层次结构
  • 将来,如果您决定选择另一个库进行本地化,则只需更改该Context的主要Provider组件,它将在整个应用程序中更新实现。
  • 由于翻译是最初加载的,因此您的上下文不会更新,并且不会再次出现问题。

答案 3 :(得分:0)

如果您在编码React组件时使用hooks,而不是类(像我一样),则可以使用useTranslation钩子:

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>
}

这就像withTranslation包装器一样,需要在每个使用翻译的文件中导入(挂钩)。