Использование response-i18next t функционирует вне компонентов. Проблемы с использованием обещаний правильно - PullRequest
1 голос
/ 18 октября 2019

Прежде всего, я хочу сказать, что я относительно новичок в React и ES6 в целом.

До сих пор я с большим успехом реализовал реакцию-i18next в компонентах. Я также добавил сканер i18next для автоматического извлечения ключей перевода в файлы .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

routs / 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> для генерации строк кажется неправильным. И установка пустых строк и их перезапись позже с помощью обещания не будет выглядеть элегантно.

Я все еще хочу иметь возможность извлекать ключи с помощью сканера. Это делает решение передать ключи для последующего использования с функцией t() в компоненте боковой панели хлопотным. Сканер не распознает динамические переводы с использованием переменных.

Мои вопросы

Чего мне не хватает? Как должно выглядеть правильное обещание? Как правильно переводить строки за пределы компонентов?

Я, вероятно, думаю об этом неправильно. Но, как я уже говорил во вступлении, я не очень опытный разработчик JS / React, и мои предварительные знания и опыт обещаний ограничены. Я чувствую, что мое решение использовать обещания неправильно реализовано. И я бы хотел, чтобы окончательное решение можно было сканировать с помощью экстрактора ключей.

Когда пользователь меняет язык с помощью i18n.changeLanguage(lng), ключи перевода, которые генерируются вне компонентов, не обновляются. Каков наилучший подход для их обновления?

Все отзывы и помощь приветствуются.

1 Ответ

0 голосов
/ 21 октября 2019

Я нашел то, что, по моему мнению, является хорошим решением моих проблем. В этом случае нет необходимости использовать обещание. Я могу решить эту проблему двумя способами:

1) Перепишите routes/index.js, чтобы взять функцию t() в качестве аргумента. Передайте эту функцию из компонента при рендеринге (используя ловушку i18next или HOC).

2) Используйте ключи перевода в routes/index.js и переведите их при рендеринге в компоненте. Чтобы иметь возможность сканировать ключи, добавьте фиктивную функцию, которая принимает ключ в качестве аргумента и просто возвращает его. Добавьте эту функцию в сканер. Один из способов сделать это - добавить следующее в файл i18n.js.

export const tk = (key) => key;

Если у кого-то есть лучшее решение или он хочет объяснить, как правильно использовать обещание, возвращаемое i18next, яВо все уши! :)

...