使用react-i18next功能外部组件。不能正确使用Promise

时间:2019-10-18 13:46:11

标签: reactjs i18next react-i18next

首先,我想说一下,我对React和ES6总体而言还比较陌生。

到目前为止,我已经实现了react-i18next并在组件方面取得了巨大成功。我还添加了i18next-scanner以自动将翻译密钥提取到.json文件。

我有一个router/index.js文件,其中包含我的项目的路线。此文件还用于创建侧边栏导航。

在此文件中,我具有用于边栏导航的名称。路由存储为可能包含子路由的对象。我的问题是我想使用i18next t()函数来翻译这些名称。

我的代码

i18n.js:

// i18n.js
import i18next from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-xhr-backend';
import LanguageDetector from 'i18next-browser-languagedetector';

const i18n = i18next
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    debug: true,
    // ...
    },
  });

export { i18next }; // instance
export default i18n; // promise

routes / index.js:

// routes/index.js
import React from 'react';
import i18n, { i18next } from 'i18n';
import { Trans } from 'react-i18next';
// other imports...

// Does not work since the translations aren't loaded yet.
const dashboardRoute = {
  name: i18next.t('dashboard'),
  path: '/',
  component: MyPageComponent,
  children: null,
};

// Solution 1: Trans component for generating strings
const dashboardRouteTrans = {
  name: <Trans i18nKey="dashboard" />,
  path: '/',
  component: MyPageComponent,
  children: null,
};

// Solution 2: Use promise to rewrite string
const dashboardRoutePromise = {
  name: '', // Init with empty string
  path: '/',
  component: MyPageComponent,
  children: null,
};

i18n.then(function(t) {
  // Overwrite with translated string using promise
  dashboardRoutePromise.name = t('dashboard');
});

export default [
  dashboardRoute,
  dashboardRouteTrans,
  dashboardRoutePromise
];

问题

到目前为止,我提出了两个解决方案。但是感觉应该有更好的方法来实现这一点。使用<Trans>组件生成字符串感觉很错误。设置空字符串并稍后使用promise覆盖这些字符串根本感觉并不优雅。

我希望仍然能够使用扫描仪提取密钥。这使得传递键以稍后与边栏组件中的t()函数一起使用的解决方案很麻烦。扫描程序不会使用变量进行动态翻译。

我的问题

我想念什么?正确的承诺解决方案应该如何看待?在组件外部翻译字符串的正确方法是什么?

我可能在错误地考虑这一点。但是正如我在简介中所述,我不是经验丰富的JS / React开发人员,并且我以前对promise的了解和经验有限。我觉得我使用诺言的解决方案实施错误。而且,我希望最终的解决方案可以被密钥提取器扫描。

当用户使用i18n.changeLanguage(lng)更改语言时,在组件外部生成的翻译键不会更新。最好的更新方法是什么?

非常感谢所有反馈和帮助。

1 个答案:

答案 0 :(得分:0)

我发现我认为是解决问题的好方法。在这种情况下,实际上没有必要使用promise。我可以通过两种方式解决此问题:

1)重写routes/index.js,以将t()函数用作参数。从渲染器上的组件传递此功能(使用i18next挂钩或HOC)。

2)使用routes/index.js中的转换键,并在渲染时在组件中转换它们。为了能够扫描键,请添加一个以键为参数并简单返回它的伪函数。将此功能添加到扫描仪。一种方法是将以下内容添加到i18n.js文件中。

export const tk = (key) => key;

如果有人有更好的解决方案,或者想解释如何正确使用i18next返回的promise,我将不胜感激! :)