You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展:React-i18next初始化后无法读取Chrome存储更新语言

问题描述

我正在用React、TypeScript和i18next开发Chrome扩展,将用户偏好语言存储在Chrome storage中。初始化时从存储获取语言并调用i18n.changeLanguage(),尽管语言切换看似成功,但组件仍渲染默认语言(vi-VN)。

相关代码文件

  • i18n/index.ts:初始化i18next并读取存储中的语言
  • i18n/settings.ts:定义i18next的语言、命名空间和配置选项
  • index.tsx:包含语言切换按钮和翻译文本展示的主组件
  • helper.tsx:渲染React组件的工具函数

复现步骤

  1. 安装扩展
  2. 选择与回退语言不同的语言(例如en-US)
  3. 观察UI仍显示回退语言(vi-VN)
  4. 点击对应语言的切换按钮(例如“切换为英语”)
  5. UI现在更新并显示正确语言

预期行为

UI应在初始加载时显示从Chrome存储获取的语言,无需手动切换。

实际行为

UI显示默认语言,直到手动触发语言切换。

疑问

  1. 我使用存储的语言初始化i18next的方式是否正确?如果不正确,更好的方式是什么?
  2. 为何调用i18n.changeLanguage()后组件中的语言未更新?
  3. 如何确保UI在初始加载时反映Chrome存储中的正确语言?

补充信息

  • 已附上项目相关代码片段供参考
  • i18n/index.ts中的控制台日志确认已从存储中获取到正确语言

使用技术栈

  • Webpack
  • ReactJs
  • Typescript
  • I18next
  • React-i18next

代码片段

project/src/helper.tsx

import ReactDOM from 'react-dom/client';
import React from 'react';

export function renderReact(
  component: React.ReactNode,
  container?: HTMLElement,
) {
  if (!container) {
    container = document.createElement('div');
    document.body.appendChild(container);
  }
  const root = ReactDOM.createRoot(container);
  root.render(<React.StrictMode>{component}</React.StrictMode>);
}

project/src/index.tsx

import { useTranslation } from './i18n';
import { useState } from 'react';

const Home = () => {
  const { t, i18n } = useTranslation();
  const [currentLanguage, setCurrentLanguage] = useState(i18n.language);

  /// 手动切换时能立即生效,工作正常
  const handleChangeLanguage = async (newLanguage: string) => {
    setCurrentLanguage(newLanguage);
    await i18n.changeLanguage(newLanguage);
    await chrome.storage.sync.set({ language: newLanguage });
  };
  return (
    <>
      Test: {t('s')}
      <div>
        <button
          className={cn('dl-bg-blue-900 dl-text-white dl-p-2 dl-rounded')}
          onClick={() => handleChangeLanguage('en-US')}
        >
          切换为英语
        </button>
      </div>
      <div>
        <button
          className={cn('dl-bg-blue-900 dl-text-white dl-p-2 dl-rounded')}
          onClick={() => handleChangeLanguage('vi-VN')}
        >
          切换为越南语
        </button>
      </div>
    </>
  );
}
renderReact(<Home />);

project/src/i18n/index.ts

import i18n from 'i18next';
import resourcesToBackend from 'i18next-resources-to-backend';
import { defaultNS, getOptions, languages } from './settings';
import {
  initReactI18next,
  useTranslation as useTranslationOriginal,
} from 'react-i18next';
i18n
  .use(initReactI18next)
  .use(
    resourcesToBackend((language: string, namespace: string) =>
      require(`./locales/${language}/${namespace}.json`),
    ),
  )
  .init({
    ...getOptions(),
  })
  .then(() => {
    chrome.storage.sync.get(['language'], (result: any) => {
      if (result.hasOwnProperty('language') && result.language) {
        console.log('i18n', result.language); // 输出: en-US
        i18n.changeLanguage(result.language); // 调用了语言切换,但index.tsx仍使用回退语言
      }
    });
  });

export function useTranslation(
  lng?: string,
  ns: string = defaultNS,
  options: any = {},
) {
  const ret = useTranslationOriginal(ns, options);
  const { i18n } = ret;
  if (
    lng &&
    i18n.resolvedLanguage !== lng &&
    Object.keys(languages).includes(lng)
  ) {
    i18n.changeLanguage(lng);
  }
  return ret;
}

project/src/i18n/settings.ts

export const fallbackLng = 'vi-VN';
export const languages = {
  'vi-VN': 'Vietnamese',
  'en-US': 'English(US)',
};
export const defaultNS = 'translation';

export function getOptions(lng = fallbackLng, ns = defaultNS) {
  return {
    // debug: true,
    supportedLngs: Object.keys(languages),
    fallbackLng,
    lng,
    fallbackNS: defaultNS,
    defaultNS,
    ns,
  };
}

project/src/i18n/locales/vi-VN/translation.json

{
  "s": "Test Vietnamese"
}

project/src/i18n/locales/en-US/translation.json

{
  "s": "Test English"
}

内容的提问来源于stack exchange,提问作者VQH DEV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:09:51