React 实现 i18next 中英文切换集成

在 React 项目中配置 react-i18next 实现中英文切换,步骤如下:

一、安装依赖

首先确保已安装核心库:

复制代码
npm install react-i18next i18next i18next-http-backend  # 核心库 + 加载语言文件的插件

二、配置 i18n

1. 创建语言文件

public 目录下创建语言文件(推荐用 JSON 格式),结构如下:

复制代码
public/
  locales/
    en/
      translation.json  # 英文翻译
    zh/
      translation.json  # 中文翻译

内容:

  • public/locales/en/translation.json

    {
    "back": "Back",
    "createProject": "Create Project",
    "allStatus": "All Status",
    "labeling": "Labeling",
    "confirming": "Confirming",
    "completed": "Completed",
    "startDate": "Start Date",
    "endDate": "End Date",
    "searchPlaceholder": "Enter keywords to search...",
    "noProjects": "No data, you haven't created any projects yet!",
    "noFilteredProjects": "No projects match the filter criteria, please adjust the filters!",
    "loadingTip": "Loading...",
    "productType": "Product Type",
    "unknown": "Unknown",
    "confirmDelete": "Confirm Delete",
    "confirmDeleteContent": "Are you sure you want to delete this project?",
    "ok": "Confirm",
    "cancel": "Cancel",
    "deleteSuccess": "Delete Success",
    "deleteError": "Delete Failed",
    "productMaterial": "Product Material",
    "createBy": "Project Creator",
    "qualityUserName": "Quality User Name",
    "createTime": "Create Time",
    "edit": "Edit",
    "view": "View",
    "updateTime": "Update Time",
    "delete": "Delete",
    "totalProjects": "Total",
    "items": "Items",
    "createProjectModalTitle": "Create Project",
    "projectName": "Project Name",
    "drawingFiles": "Drawing Files",
    "uploadDrawingFiles": "Upload Drawing Files",
    "projectNameRequired": "Project name is required",
    "projectNameMaxLength": "Project name must be at most 50 characters",
    "projectNameWhitespace": "Project name cannot be only whitespace",
    "projectNamePlaceholder": "Enter project name",
    "drawingFilesRequired": "Drawing files are required",
    "fileFormatTip": "Supported formats: PDF, PNG, JPG. Maximum file size: 50MB. Maximum number of files: 5",
    "productTypeRequired": "Product type is required",
    "productTypeMaxLength": "Product type must be at most 20 characters",
    "productTypeWhitespace": "Product type cannot be only whitespace",
    "productTypePlaceholder": "Enter product type",
    "productMaterialRequired": "Product material is required",
    "productMaterialMaxLength": "Product material must be at most 20 characters",
    "productMaterialWhitespace": "Product material cannot be only whitespace",
    "productMaterialPlaceholder": "Enter product material",
    "vossPNRequired": "VOSS P/N is required",
    "vossPNWhitespace": "VOSS P/N cannot be only whitespace",
    "vossPNPlaceholder": "Enter VOSS P/N",
    "partDescriptionRequired": "Part description is required",
    "partDescriptionWhitespace": "Part description cannot be only whitespace",
    "partDescriptionPlaceholder": "Enter part description",
    "drawingVersionRequired": "Drawing version is required",
    "drawingVersionWhitespace": "Drawing version cannot be only whitespace",
    "drawingVersionPlaceholder": "Enter drawing version",
    "qualityManagerRequired": "Quality manager is required",
    "qualityManagerPlaceholder": "Select quality manager",
    "loadingQualityManager": "Loading quality manager...",
    "createProjectButton": "Create Project",
    "loadingQualityManagerError": "Failed to load quality manager",
    "qualityManagerInvalid": "Please select a valid quality manager",
    "drawingFileRequired": "Please upload at least one valid drawing file (ensure the file upload is complete)",
    "projectCreateSuccess": "Project created successfully!",
    "pleaseCompleteAllRequiredFields": "Please complete all required fields",
    "lastSaveTime": "Last Save Time",
    "projectManager": "Project Manager",
    "drawing": "Drawing",
    "draw": "Draw",
    "annotations": "Annotations",
    "viewReport": "View Report",
    "attachmentList": "Attachment List",
    "index": "Index",
    "screenshot": "Screenshot",
    "toleranceValue": "Value",
    "toleranceName": "Tolerance Name",
    "characteristicIdentifier": "Characteristic Identifier",
    "project": "Project",
    "normTolerance": "Normal Tolerance",
    "testingMethods": "Testing Methods",
    "testingRequirements": "Testing Requirements",
    "firstSamplingQuantity": "First Sampling Quantity",
    "afterFirstSamplingQuantity": "After First Sampling Quantity",
    "afterFirstSamplingFrequency": "After First Sampling Frequency",
    "supplierSelfTestRequirements": "Supplier Self-Test Requirements",
    "operation": "Operation",
    "ocrDetect": "OCR Detect",
    "initiateConfirmation": "Initiate Confirmation",
    "extractText": "Extract Text",
    "dragMode": "Drag Mode",
    "resetSelection": "Reset Selection",
    "boxSelectMode": "Box Select Mode",
    "singleAnnotation": "Single Annotation",
    "parsingImage": "Parsing Image",
    "confirmDeleteAnnotation": "Confirm Delete Annotation",
    "confirm": "Confirm"
    }

  • public/locales/zh/translation.json

    {
    "back": "返回",
    "createProject": "新建项目",
    "allStatus": "全部状态",
    "labeling": "标注中",
    "confirming": "确认中",
    "completed": "已完成",
    "startDate": "开始日期",
    "endDate": "结束日期",
    "searchPlaceholder": "输入关键字进行搜索...",
    "noProjects": "暂无数据,您还没有创建过任何项目!",
    "noFilteredProjects": "没有符合筛选条件的项目,请尝试调整筛选条件!",
    "loadingTip": "加载中...",
    "productType": "产品类型",
    "unknown": "未知",
    "confirmDelete": "确认删除",
    "confirmDeleteContent": "确定要删除该项目吗?",
    "ok": "确定",
    "cancel": "取消",
    "deleteSuccess": "删除成功",
    "deleteError": "删除失败",
    "productMaterial": "产品材质",
    "createBy": "项目创建人",
    "qualityUserName": "质量负责人",
    "createTime": "创建时间",
    "edit": "编辑",
    "view": "查看",
    "updateTime": "更新时间",
    "delete": "删除",
    "totalProjects": "共",
    "items": "条数据",
    "createProjectModalTitle": "新建项目",
    "projectName": "项目名称",
    "drawingFiles": "图纸文件",
    "uploadDrawingFiles": "选择附件",
    "projectNameRequired": "请填写项目名称",
    "projectNameMaxLength": "项目名称最多50个字符",
    "projectNameWhitespace": "项目名称不能仅为空格",
    "projectNamePlaceholder": "请输入项目名称",
    "drawingFilesRequired": "请上传图纸文件",
    "fileFormatTip": "支持PDF、PNG、JPG格式,大小≤50MB的图档,一次性最多上传5张",
    "productTypeRequired": "请填写产品类型",
    "productTypeMaxLength": "产品类型最多20个字符",
    "productTypeWhitespace": "产品类型不能仅为空格",
    "productTypePlaceholder": "请输入产品类型",
    "productMaterialRequired": "请填写产品材质",
    "productMaterialMaxLength": "产品材质最多20个字符",
    "productMaterialWhitespace": "产品材质不能仅为空格",
    "productMaterialPlaceholder": "请输入产品材质",
    "vossPNRequired": "请填写VOSS P/N",
    "vossPNWhitespace": "VOSS P/N不能仅为空格",
    "vossPNPlaceholder": "请输入VOSS P/N",
    "partDescriptionRequired": "请填写Part description",
    "partDescriptionWhitespace": "Part description不能仅为空格",
    "partDescriptionPlaceholder": "请输入Part description",
    "drawingVersionRequired": "请填写Drawing Version",
    "drawingVersionWhitespace": "Drawing Version不能仅为空格",
    "drawingVersionPlaceholder": "请输入Drawing Version",
    "qualityManagerRequired": "请选择质量负责人",
    "qualityManagerPlaceholder": "请选择质量负责人",
    "loadingQualityManager": "加载质量负责人中...",
    "createProjectButton": "立即创建",
    "loadingQualityManagerError": "加载质量负责人失败",
    "qualityManagerInvalid": "请选择有效的质量负责人",
    "drawingFileRequired": "请上传至少一个有效的图纸文件(确保文件上传完成)",
    "projectCreateSuccess": "项目创建成功!",
    "pleaseCompleteAllRequiredFields": "请完善所有必填项信息",
    "lastSaveTime": "上次保存时间",
    "projectManager": "项目负责人",
    "drawing": "图纸",
    "draw": "图",
    "annotations": "标注点位",
    "viewReport": "查看基准书报表",
    "attachmentList": "附件清单",
    "index": "序号",
    "screenshot": "截图",
    "toleranceValue": "数值",
    "toleranceName": "公差名称",
    "characteristicIdentifier": "特性标识",
    "project": "项目",
    "normTolerance": "规范公差",
    "testingMethods": "检验手段",
    "testingRequirements": "福士来料检验要求",
    "firstSamplingQuantity": "首批抽样数量",
    "afterFirstSamplingQuantity": "首批后抽样数量",
    "afterFirstSamplingFrequency": "首批后抽样频次",
    "supplierSelfTestRequirements": "供方自检要求",
    "operation": "操作",
    "ocrDetect": "AI标注气泡",
    "initiateConfirmation": "发起确认",
    "extractText": "文字提取",
    "dragMode": "拖拽模式",
    "resetSelection": "重置框选",
    "boxSelectMode": "框选模式",
    "singleAnnotation": "单点标注",
    "parsingImage": "正在解析图片",
    "confirmDeleteAnnotation": "是否确认删除该标注?",
    "confirm": "确认"
    }

2. 创建 i18n 配置文件

src 目录下新建 i18n.js

复制代码
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';

i18n
    .use(Backend) // 加载语言文件
    .use(initReactI18next)
    .init({
        fallbackLng: 'zh', // 默认语言
        debug: false,
        interpolation: {
            escapeValue: false, // 允许使用变量(如 {{total}})
        },
        // 配置语言文件路径(默认会从 public/locales/{{lng}}/{{ns}}.json 加载)
        backend: {
            loadPath: '/locales/{{lng}}/{{ns}}.json'
        }
    });

export default i18n;
3. 在入口文件引入配置

src/main.jsx 中引入 i18n.js,确保初始化:

复制代码
import './i18n';

三、在组件中使用

1. 基础用法(翻译文本)

使用 useTranslation 钩子获取翻译函数:

复制代码
import { useTranslation } from 'react-i18next';

function Home() {
  const { t } = useTranslation(); // t 是翻译函数

  return (
    <div>
      <h1>{t('welcome')}</h1>
      <p>{t('description')}</p>
    </div>
  );
}

export default Home;
2. 切换语言

通过 i18n.changeLanguage 方法切换语言:

复制代码
import { useTranslation } from 'react-i18next';

const HomePage = () => {
    const { t, i18n } = useTranslation();

    const changeLang = (lang) => {
        i18n.changeLanguage(lang); // 切换语言('en' 或 'zh')
    };

    return (
        <div className={styles['page-header']}>
        <div className={styles['header-content']}>
          <Button
            type="text"
            icon={<ArrowLeftOutlined />}
            onClick={handleBack}
            className={styles['back-button']}
          >
            {t('back')}
          </Button>
          <div className={styles['right-actions']}>
            <Dropdown
              menu={{
                items: [
                  {
                    key: 'zh',
                    label: '简体中文'
                  },
                  {
                    key: 'en',
                    label: 'English'
                  }
                ],
                onClick: ({ key }) => {
                  changeLang(key);
                }
              }}
              placement="bottomRight"
            >
              <div className={styles.languageSwitcher}>
                <span className={styles.currentLang}>
                  {i18n.language === 'zh' ? '简体中文' : 'English'}
                </span>
                <div className={styles.langIcon}>
                  <GlobalOutlined />
                </div>
              </div>
            </Dropdown>
            <Button
              type="primary"
              icon={<PlusOutlined />}
              onClick={() => setModalVisible(true)}
              className={styles['create-button']}
            >
              {t('createProject')}
            </Button>
          </div>
        </div>
        <div className={styles['divider-line']}></div>
      </div>
    )
}

export default HomePage;

效果

3.DatePicker 随切换更新中英文(可选)

添加当前语言的状态定义逻辑

复制代码
import zhCN from 'antd/locale/zh_CN';
import enUS from 'antd/locale/en_US';

const [currentLang, setCurrentLang] = useState(i18n.language);

const changeLang = (lang) => {
    i18n.changeLanguage(lang); // 切换语言('en' 或 'zh')
    setCurrentLang(lang); // 更新当前语言状态
  };

 <ConfigProvider locale={currentLang === 'zh' ? zhCN : enUS}>
              <DatePicker.RangePicker
                size="large"
                value={timeFilter}
                onChange={handleTimeChange}
                placeholder={[t('startDate'), t('endDate')]}
                className={styles['time-filter']}
              />
            </ConfigProvider>

效果

四、进阶配置(可选)

  1. 动态加载语言i18next-http-backend 会自动加载对应语言文件,无需手动引入。

  2. 保存语言偏好 :配置 detection 中的 caches 后,语言选择会保存在 localStoragecookie 中,刷新页面不会重置。

  3. 嵌套翻译:语言文件支持嵌套结构,例如:

    {
    "user": {
    "name": "姓名",
    "age": "年龄"
    }
    }

使用时:t('user.name')

五、其余子组件效果(按需实现即可)

其余组件需要使用也是直接通过下方主要代码实现

复制代码
import { useTranslation } from 'react-i18next';


const { t } = useTranslation();


{t('productType')}

t 函数可以用于 DOM、实际函数中(例如:创建成功之后message.success(t('projectCreateSuccess'));或者message.error(t('pleaseCompleteAllRequiredFields'));......)按需修改即可

以下展示一个新建弹窗翻译后的效果:

六、实现本地存储

修改 i18n 文件

复制代码
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';

i18n
    .use(Backend) // 加载语言文件
    .use(initReactI18next)
    .init({
        fallbackLng: 'zh',
        // 初始化时优先读取本地存储的语言,无则用默认中文
        lng: localStorage.getItem('selectedLang') || 'zh',
        debug: false,
        interpolation: {
            escapeValue: false,
        }
    });

export default i18n;

添加本地存储逻辑

复制代码
const [currentLang, setCurrentLang] = useState(localStorage.getItem('selectedLang') || i18n.language);

  const changeLang = (lang) => {
    i18n.changeLanguage(lang); // 切换语言('en' 或 'zh')
    setCurrentLang(lang); // 更新当前语言状态
    localStorage.setItem('selectedLang', lang);
  };

  useEffect(() => {
    // 组件挂载时,读取本地存储语言并同步到 i18n 和 currentLang
    const storedLang = localStorage.getItem('selectedLang');
    if (storedLang) {
      i18n.changeLanguage(storedLang);
      setCurrentLang(storedLang);
    }
  }, [i18n]);



<span className={styles.currentLang}>
                  {currentLang === 'zh' ? '简体中文' : 'English'}
                </span>

通过以上配置,即可实现 React 项目的中英文切换功能。核心是通过 t() 函数获取翻译文本,通过 i18n.changeLanguage() 切换语言。

相关推荐
啃火龙果的兔子3 小时前
前端八股文react篇
前端·react.js·前端框架
拉不动的猪3 小时前
函数组件和异步组件
前端·javascript·面试
淮北4943 小时前
html + css +js
开发语言·前端·javascript·css·html
你的人类朋友3 小时前
适配器模式:适配就完事了bro!
前端·后端·设计模式
Setsuna_F_Seiei4 小时前
CocosCreator 游戏开发 - 利用 AssetsBundle 技术对小游戏包体积进行优化
前端·cocos creator·游戏开发
黄毛火烧雪下4 小时前
高效的项目构建和优化之前端构建工具
前端
90后的晨仔4 小时前
在 macOS 上轻松获取 GIF 图片总时长:多种实用方法详解
前端
技术钱4 小时前
vue3前端解析excel文件
前端·vue.js·excel
mapbar_front5 小时前
顺利通过试用期:避开三大陷阱,掌握三个关键点
前端·面试