在 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>
效果
四、進階配置(可選)
- 動態加載語言:
i18next-http-backend會自動加載對應語言文件,無需手動引入。 - 保存語言偏好:配置
detection中的caches後,語言選擇會保存在localStorage或cookie中,刷新頁面不會重置。 - 嵌套翻譯:語言文件支持嵌套結構,例如:
{
"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() 切換語言。