React-intl анализирует массив json в файле локали

В настоящее время я работаю с React-intl v. ^4.7.6. У меня есть папка с именем translations, в которой находятся все мои языковые переводы. Я использую IntlProvider, чтобы выбрать файл для загрузки в зависимости от браузера пользователя. Кажется, что FormatttedMessage или intl.formatMessage не могут этого сделать.

Вот как выглядит мой файл перевода. Конечно, будет по одному для каждого языка. transtions/eng.json

{
  "header.about": "About",
  "header.resume": "Resume",
  "Education": [{
    "school": "ABC University",
    "degree": "(B.Eng)",
    "graduated": "2030 - Present",
    "location": "Canada",
    "description": [
      "d1",
      "d2"
    ]
  },
    {
      "school": "College",
      "degree": "Science",
      "graduated": "2030",
      "location": "Canada",
      "description": [
        "Graduated with honors"
      ]
    }]

[... other translations ...]
}

person bobob    schedule 23.08.2020    source источник
comment
Помогает ли вам этот один? Вы используете CRA или/и машинопись?   -  person NearHuscarl    schedule 24.08.2020
comment
Я использую typescript, но, к сожалению, это не помогает. Файл Json загружается IntlProvider в зависимости от языка браузера пользователя.   -  person bobob    schedule 24.08.2020
comment
Если вы используете машинописный текст, проверьте, установлено ли для resolveJsonModule значение true в вашем tsconfig.json   -  person NearHuscarl    schedule 24.08.2020


Ответы (1)


У меня есть другой подход к решению вашей проблемы. (Хотя это может быть не лучшее решение, и это не совсем ваш английский/немецкий перевод, но я думаю, что они похожи)

Сначала мы можем определить файл со всеми ключами локализации:

// i18n/keys.js 
export const student = {
 
  projects: [
    {
      name: "student.projects.0.name",
      desc: "student.projects.0.desc",
    },
    {
      name: "student.projects.1.name",
      desc: "student.projects.1.desc",
    },
  ],
};

export const localizationKeys = {
  student: student,
};

В файлах локали i18n мы можем определить переводы, как показано ниже:

// i18n/en/student.js
export const student = {
  projects: [
    {
      name: "Camera",
      desc: "Photo",
    },
    {
      name: "Foods",
      desc: "Apple",
    },
  ],
};

// i18n/zh_tw/student.js
export const student = {
  projects: [
    {
      name: "拍攝",
      desc: "照片",
    },
    {
      name: "食物",
      desc: "蘋果",
    },
  ],
};

Экспортируйте переводы из i18n в языковые модули для react-i18n.

// i18n/en/index.js
import { student } from "./student";

const en = {
  general: general,
};

export default en;

// i18n/zh_tw/index.js
import { student } from "./student";

const zh_tw = {
  student: student,
};

export default zh_tw;

В ваших компонентах реакции вы можете получить доступ к своим ключам локализации (keys.js), чтобы вернуть каждое из имен ключей i18n.

import React from "react";
import { useIntl } from "react-intl";
import { localizationKeys } from "./i18n/keys";
import { IntlProvider } from "react-intl";
import zh_tw from "./i18n/zh_tw";
import flatten from "flat";
import en from "./i18n/en";

const messages = {
  en: flatten(en),
  "zh-Hant-TW": flatten(zh_tw),
};

export default function ProjectShowcase() => {
  const intl = useIntl();
  const [locale, setLocale] = useState(navigator.language);
  const [mergedMessages, setMergedMessages] = useState(messages["en"]);

  useEffect(() => {
    // Merging english and current locale, avoid showing Text id if cannot look for the translate in locale file
    // In this case, it will always show EN translate as default if the text-id not found in a "zh_tw" locale
    setMergedMessages(Object.assign({}, messages["en"], messages[locale]));
  }, [locale]);
  
  return (
  <IntlProvider
      messages={mergedMessages}
      locale={locale}
      key={locale}
      defaultLocale="en"
    >
    {localizationKeys.student.projects.map((p, idx) => {
        return (
          <ul>
            <li>
              <span>
                {intl.formatMessage({
                  id: localizationKeys.student.projects[idx].name,
                })}
              </span>
              {` (${intl.formatMessage({
                id: localizationKeys.student.projects[idx].desc,
              })})`}
            </li>
          </ul>
        );
      })
    }
 </IntlProvider>
  )
}

Я разработал небольшой пример для react-intl, вы можете найти более законченный код внутри: https://github.com/applelok/react-localization

person appletabo    schedule 13.10.2020
comment
TL:DR Рефакторинг массивов вне файлов локалей для получения аналогичного поведения. Слишком много работы, имхо. - person ferit; 15.07.2021