React locales 国际化

105 阅读2分钟

demo-locales:React locales 国际化

代码仓库

github.com/chuxin-cs/r…

主线任务

1、基于 Vite 项目,目录结构如下:

2、项目所需依赖:

pnpm add i18next react-i18next i18next-browser-languagedetector -S

3、lang 相关配置,以 zh_CN代码举例:

// common.json
{
	"common": {
        "light": "亮色主题",
        "dark": "黑暗主题"
	}
}
// system.json
{
	"system": {
		"docs": "文档",
		"api": {
                "title": "我是接口API"
		},
		"settings": {
                "title": "设置"
		}
	}
}
// index.ts
import common from "./common.json";
import system from "./system.json";

export default {
	...common,
	...system,
};

4、locales/i18n.ts:

// 导入 i18next 库,用于实现国际化功能
import i18n from 'i18next';
// 导入 react-i18next 中的 initReactI18next,用于将 i18next 集成到 React 应用中
import { initReactI18next } from 'react-i18next';
// 导入 i18next-browser-languagedetector,用于自动检测用户的浏览器语言
import LanguageDetector from 'i18next-browser-languagedetector';

// 导入英文翻译资源文件
import en_US from './lang/en_US';
// 导入中文翻译资源文件
import zh_CN from './lang/zh_CN';

// 配置 i18next 实例
i18n
  // 使用语言检测器自动检测用户的浏览器语言
  .use(LanguageDetector)
  // 将 i18next 集成到 React 应用中
  .use(initReactI18next)
  // 初始化 i18next 实例
  .init({
    // 开启调试模式,会在控制台输出调试信息
    debug: true,
    // 当检测不到用户语言时,使用的备用语言
    fallbackLng: 'zh_CN',
    // 插值配置,设置为 false 表示不转义插值的值
    interpolation: {
      escapeValue: false,
    },
    // 翻译资源配置,包含英文和中文的翻译资源
    resources: {
      en_US: { translation: en_US },
      zh_CN: { translation: zh_CN },
    },
  });

// 导出默认的 i18next 实例
export default i18n;
// 从 i18next 实例中解构导出 t 函数,用于在组件中进行翻译
export const { t } = i18n;

5、locales/use-locale.ts

import { useTranslation } from 'react-i18next';

// 定义类型
export enum LocalEnum {
	en_US = "en_US",
	zh_CN = "zh_CN",
}
type Locale = keyof typeof LocalEnum;

export const useLocale = () => {
  const { i18n } = useTranslation();
  const locale = i18n.resolvedLanguage as Locale;

  const setLocale = (locale: Locale) => {
    i18n.changeLanguage(locale);
  };

  return {
    locale,
    setLocale,
  };
};

6、main.tsx 中:

import { createRoot } from 'react-dom/client';
import App from './App.tsx';

// i18n 国际化
import "./locales/i18n";

const root = createRoot(document.getElementById('root')!);
root.render(<App />);

7、App.tsx 中验证:

import { useState } from 'react';
import { t } from './locales/i18n';
import { useLocale } from './locales/use-locale';

function App() {
  const { setLocale } = useLocale();
  return (
    <div>
      <div>
        <button onClick={() => setLocale('zh_CN')}>中文</button>
        <button onClick={() => setLocale('en_US')}>english</button>
      </div>
      <h1>{t('system.api.title')}</h1>
      <h2>{t("common.light")}</h2>
    </div>
  );
}

export default App;

7、i18n会自动缓存当前主题: LocalStorage keyi18nextLng

支线任务

dayjs

import { useTranslation } from 'react-i18next';

import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';

// 定义类型
export enum LocalEnum {
  en_US = 'en_US',
  zh_CN = 'zh_CN',
}
type Locale = keyof typeof LocalEnum;

export const useLocale = () => {
  const { i18n } = useTranslation();
  const locale = (i18n.resolvedLanguage || LocalEnum.en_US) as Locale;

  const setLocale = (locale: Locale) => {
    i18n.changeLanguage(locale);
    dayjs.locale(locale);
  };

  return {
    locale,
    setLocale,
  };
};

export default useLocale;