我对复杂的React应用程序的多语言支持有疑问。所有示例和文档均基于无嵌套/子组件的“扁平”应用程序。
如何处理像这样嵌套的数据:
<i18n>
<App>
translate('base')(
<Base>
<Child1 />
<Child2 />
{t('Hello')}
</Base>
)
</App>
</i18n>
我应该用translate
HOC包装每个子组件吗?还是有其他方法可以将翻译功能传递给子组件?
答案 0 :(得分:8)
I had the same problem not long ago. There are 4 solutions I found for this.
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.
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.
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.
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
属性作为上下文,并在每个嵌套的子组件中对其进行访问。
我也在这样的应用程序中使用本地化。
优点:
答案 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包装器一样,需要在每个使用翻译的文件中导入(挂钩)。