常见误区
很多开发者认为国际化是大公司的专利,或者觉得业务只面向国内用户就不需要。这种想法往往在业务拓展到海外时带来巨大麻烦:临时抱佛脚、满世界找字符串替换,甚至依赖机器翻译导致体验糟糕。
国际化不是可选项,而是现代前端开发的标配。
为什么需要国际化
- 全球用户覆盖:吸引不同国家和地区的用户
- 业务拓展:为未来的海外市场做准备
- 用户体验:让用户使用熟悉的语言环境
- 品牌形象:展现专业、全球化的企业形象
错误示范
硬编码字符串是最常见的反模式。当需要支持多语言时,维护成本会指数级上升。
// 反面教材:硬编码字符串
function Header() {
return (
<div className="header">
<h1>欢迎来到我的网站</h1>
<nav>
<a href="/">首页</a>
<a href="/about">关于我们</a>
<a href="/contact">联系我们</a>
</nav>
</div>
);
}
// 反面教材:手动切换语言
function App() {
const [language, setLanguage] = useState('zh');
const getText = (key) => {
const texts = {
zh: { welcome: '欢迎', about: '关于我们', contact: '联系我们' },
en: { welcome: 'Welcome', about: 'About Us', contact: 'Contact Us' }
};
return texts[language][key];
};
return (
<div>
<button onClick={() => setLanguage('zh')}>中文</button>
<button onClick={() => setLanguage('en')}>English</button>
<h1>{getText('welcome')}</h1>
</div>
);
}
这种写法不仅代码冗余,而且难以扩展和维护。一旦增加一种语言,所有组件都要修改。
推荐方案
使用专业的国际化库,如 i18next,配合 React 生态的 react-i18next。这能统一管理翻译资源,支持参数化、复数形式及自动检测。
1. 安装依赖
npm install i18next react-i18next
2. 初始化配置
创建 i18n.js 文件进行全局配置。
// i18n.js
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import zh from './locales/zh.json';
import en from './locales/en.json';
i18n
.use(initReactI18next)
.init({
resources: {
zh: { translation: zh },
en: { translation: en }
},
lng: 'zh', // 默认语言
fallbackLng: 'en', // 回退语言
interpolation: {
escapeValue: false // React 已默认转义
}
});
export default i18n;
3. 翻译资源管理
将文本提取到独立的 JSON 文件中,便于维护和协作。
// locales/zh.json
{
"welcome": "欢迎来到我的网站",
"nav": {
"home": "首页",
"about": "关于我们",
"contact": "联系我们"
},
"greeting": "你好,{{name}}!",
"count": "你有 {{count}} 条消息"
}
// locales/en.json
{
"welcome": "Welcome to my website",
"nav": {
"home": "Home",
"about": "About Us",
"contact": "Contact Us"
},
"greeting": "Hello, {{name}}!",
"count": "You have {{count}} messages"
}
4. 组件集成
在组件中使用 useTranslation Hook 获取翻译函数。
import React from 'react';
import { useTranslation } from 'react-i18next';
function Header() {
const { t } = useTranslation();
return (
<div className="header">
<h1>{t('welcome')}</h1>
<nav>
<a href="/">{t('nav.home')}</a>
<a href="/about">{t('nav.about')}</a>
<a href="/contact">{t('nav.contact')}</a>
</nav>
</div>
);
}
function Greeting({ name }) {
const { t } = useTranslation();
return (
<div>
{/* 带参数的翻译 */}
<p>{t('greeting', { name })}</p>
</div>
);
}
function MessageCount({ count }) {
const { t } = useTranslation();
return (
<div>
{/* 复数形式 */}
<p>{t('count', { count })}</p>
</div>
);
}
5. 语言切换
通过 i18n.changeLanguage 动态切换当前语言。
import React from 'react';
import { useTranslation } from 'react-i18next';
function LanguageSwitcher() {
const { i18n } = useTranslation();
const changeLanguage = (lng) => {
i18n.changeLanguage(lng);
};
return (
<div className="language-switcher">
<button onClick={() => changeLanguage('zh')}>中文</button>
<button onClick={() => changeLanguage('en')}>English</button>
</div>
);
}
核心要点
国际化不仅仅是翻译文本,还涉及日期、时间、数字、货币格式的本地化,以及 RTL(从右到左)语言的支持。
- 使用专业库:如 i18next、react-intl 等
- 统一管理资源:翻译文本放在单独的 JSON 文件中
- 参数化翻译:处理带变量的文本
- 复数形式支持:根据数量变化显示不同文本
- 自动检测语言:根据浏览器设置自动切换
- 本地化格式:处理日期、时间、数字等格式
- RTL 支持:适配阿拉伯语等从右到左的语言
- 懒加载翻译:按需加载资源,减少包大小
总结
做好国际化能让你的产品具备全球视野。不要等到业务出海时才匆忙补救,尽早采用规范化的方案,能显著降低后续维护成本并提升用户体验。
