【问题标题】:Using react-i18next with React standalone component - 'missingKey' error将 react-i18next 与 React 独立组件一起使用 - 'missingKey' 错误
【发布时间】:2021-01-10 10:20:23
【问题描述】:

我从 i18next 收到“missingKey”错误消息,即使翻译似乎正在加载(可以查看控制台日志记录)。我在这里做错了什么?

这是我的 i18n.js 文件:

import i18n from 'i18next'
import i18nhttp from 'i18next-http-backend'
import Backend from 'i18next-chained-backend'
import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next'

const options = {
  backends: [
    i18nhttp
  ],
    
  backendOptions: [
    { loadPath: '/api/constants/{{lng}}/{{ns}}.lang.json' }
  ]
}

i18n.use(Backend).use(LanguageDetector).use(initReactI18next).init({
  backend: options,
  ns: ['fin'],
  defaultNS: 'fin',
  fallbackNS: 'fin',
  fallbackLng: 'en',
  keySeparator: false,
  debug: true,
  detection: {
    order: ['queryString', 'cookie'],
    cache: ['cookie'],
    lookupCookie:'website#lang',
  },
  interpolation: {
    escapeValue: false
  },
  react: {
    useSuspense: true
  }
}, (err, t) => {
  if (err) return console.log('something went wrong loading', err);
  t('pinDescription') 
})

export default i18n

这是我的 React 组件文件:

import React, { Suspense }  from 'react'
import ReactDOM from 'react-dom'
import '../../../scripts/i18n'
import { useTranslation } from 'react-i18next'

  const Translation = () => {
    const { t, i18n } = useTranslation()
  
    return (
      <div className="translation-sample">
        <h2>Translation Sample - from files</h2>
        <p>{t('accountNumberDescription')}</p>
      </div>
    )
  }

  const domElement = document.getElementById('translation-sample')

  if (domElement) {
    ReactDOM.render(
      <React.StrictMode>
        <Suspense fallback={<div>Loading ... </div>}>
          <Translation />
        </Suspense>
      </React.StrictMode>,
      domElement
    );
  }

对于我尝试在 init 回调 (t('pinDescription')) 中呈现的翻译,我收到此错误:

i18next::translator: key "pinDescription" for languages "en" won't get resolved as namespace "fin" was not yet loaded This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!

这很奇怪,因为 react-i81n 文档表明此回调在翻译加载后运行。

为此,对于我尝试在组件中呈现的键,我也会收到“缺少键”错误:

i18next::translator: missingKey en fin pinDescription pinDescription
i18next::translator: missingKey en fin accountDescription accountDescription

我尝试了几件事,包括:

  1. 将 init 调用包装在一个 Promise 中,导出该函数并在组件中等待它
  2. 使用 HOC 方法
  3. 从 i18n.js 文件中导出 i18n 实例,然后将其导入组件中并调用 init(尝试了 awaiting 和 promise / then)

此外,如果我使用 Suspense 包装器组件,我会看到翻译已加载到控制台中(但是我仍然会丢失关键错误)。当我在 i81n.js 配置中删除“Suspense”并选择退出时,我从未在控制台中看到任何已加载翻译的指示。

我觉得我在这里遗漏了一些基本的东西。在组件中使用“t”之前等待初始化/翻译加载过程的最佳方法是什么?

我所做的与文档中的大多数示例之间的主要区别在于它们显示 i18n.js 被加载到 React 应用程序的 index.js 文件中。我没有任何 index.js 文件或 React 应用程序 - 我正在使用单个 React 组件,该组件稍后将被注入到现有的非 React 应用程序中。

此外,没有网络错误,我可以直接在浏览器中访问语言json文件没有问题,我可以在控制台中看到翻译加载。

来自浏览器控制台的输出(我在这里使用不同的命名空间,但代码相同):

提前感谢您提供任何提示或指出我哪里出错了!

【问题讨论】:

    标签: reactjs internationalization translation i18next react-i18next


    【解决方案1】:

    你错过了i18next provider

    import React, { Suspense } from 'react';
    import ReactDOM from 'react-dom';
    import i18n from '../../../scripts/i18n';
    import { useTranslation, I18nextProvider } from 'react-i18next';
    
    const Translation = () => {
      const { t } = useTranslation();
    
      return (
        <div className="translation-sample">
          <h2>Translation Sample - from files</h2>
          <p>{t('accountNumberDescription')}</p>
        </div>
      );
    };
    
    const domElement = document.getElementById('translation-sample');
    
    if (domElement) {
      ReactDOM.render(
        <React.StrictMode>
          <I18nextProvider i18n={i18n}> // <----
            <Suspense fallback={<div>Loading ... </div>}>
              <Translation />
            </Suspense>
          </I18nextProvider>
        </React.StrictMode>,
        domElement
      );
    }
    

    【讨论】:

    • 您确定需要提供者吗?我在这里没有看到任何提及:react.i18next.com/latest/using-with-hooksreact.i18next.com/guides/quick-start
    • 我确定,你可以在useTranslation的源代码中看到它使用了useContextgithub.com/i18next/react-i18next/blob/master/src/…
    • 啊,好观察。但是看起来使用提供程序是可选的。我从 'useTranslation()' 挂钩中获取了 'i18n' 实例,但在上面发布的代码中省略了它(我在实验时将其删除)。将其添加回上面的代码 sn-p 中。
    • 您是否尝试添加提供程序?查看代码,它比使用上下文做得更多
    • 问题原来是我有另一个 i18n 实例从另一个与上述冲突的组件运行。一旦我删除,一切都开始正常工作。唯一的问题是,因为这是一个组件库而不是应用程序,所以我没有一个可以导入 i18n.js 的地方——我必须在每个组件中单独导入它。我想正确的解决方案是在客户端应用程序中导入 i18n.js 一次,但是客户端应用程序没有 React。我的项目有很多限制。感谢您的帮助。
    猜你喜欢
    • 2018-12-05
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    • 2019-07-13
    • 2018-11-09
    • 1970-01-01
    相关资源
    最近更新 更多