一个轻量级、类型安全、零心智负担的 React Native 国际化解决方案。




一个轻量级、类型安全、零心智负担的 React Native 国际化解决方案。
专为 React Native 设计,集成了最佳实践,解决了常见的国际化痛点:繁琐的配置、类型缺失、复杂的 API 以及系统语言跟随问题。
- � 零配置启动:内置智能默认值,安装即用。
- 🛡️ 极致类型安全:完全 TypeScript 编写,提供从 Key 到插值参数的完整类型推导。
- 📱 自动跟随系统:基于 react-native-localize,自动检测并响应设备语言变更。
- ⚡ 高性能:基于 i18n-js 核心,轻量高效,无多余运行时开销。
- 🔌 灵活 API:同时支持 Hook (useI18n)、高阶组件 (withI18n) 和全局函数 (t)。
- 📝 富文本支持:Trans 组件轻松处理嵌套样式和组件插值。
- 🌍 格式化内置:开箱即用的数字、货币、日期格式化支持。
``bash`
npm install react-native-i18njs或者
yarn add react-native-i18njs
> 注意:本库已内置 i18n-js 和 react-native-localize 的稳定版本,无需手动安装 peer dependencies。
建议在单独的文件中管理翻译资源,例如 src/locales/index.ts:
`ts
// src/locales/index.ts
export const translations = {
en: {
welcome: 'Welcome',
hello: 'Hello, %{name}!',
},
zh: {
welcome: '欢迎',
hello: '你好,%{name}!',
},
};
// 导出类型以获得类型提示
export type Translations = typeof translations.en;
`
在你的 App 入口文件(如 App.tsx)中初始化:
`tsx
import React from 'react';
import { initI18n, I18nProvider } from 'react-native-i18njs';
import { translations } from './src/locales';
import Home from './src/Home';
// 初始化配置
initI18n(translations, {
defaultLocale: 'en',
enableFallback: true, // 找不到翻译时回退到默认语言
});
export default function App() {
return (
// 使用 Provider 以支持语言切换时的自动重渲染
);
}
`
`tsx
// src/Home.tsx
import React from 'react';
import { Text, Button, View } from 'react-native';
import { useI18n } from 'react-native-i18njs';
import { Translations } from './locales';
export default function Home() {
// 传入泛型 Translations 以获得 key 的自动补全和类型检查
const { t, locale, setLocale } = useI18n
return (
{/ 这里的 name 参数会有类型提示 /}
);
}
`
在 Redux、Axios 拦截器、工具函数等非组件环境中,你可以直接使用全局导出的 API。
#### 基础用法
`ts
import { t, getLocale, setLocale } from 'react-native-i18njs';
// 获取当前语言
const current = getLocale();
// 切换语言
setLocale('zh');
// 直接翻译
const message = t('errors.network_timeout');
`
#### 进阶:监听语言变化
如果你需要在组件外监听语言变更(例如同步更新全局状态),可以使用顶层 subscribe 函数:
`ts
import { subscribe } from 'react-native-i18njs';
// 订阅语言变更
const unsubscribe = subscribe((locale) => {
console.log('Language changed to:', locale);
// 更新 API 默认 Header 或其他全局状态
});
// 取消订阅
// unsubscribe();
`
#### 进阶:重置为跟随系统
用户手动调用 setLocale 后会锁定语言,不再自动跟随系统。如果需要恢复跟随系统语言:
`ts
import { resetToSystem } from 'react-native-i18njs';
// 撤销用户锁定,重新跟随系统语言
resetToSystem();
`
#### 进阶:RTL 检测
`ts
import { isRTL } from 'react-native-i18njs';
if (isRTL()) {
// 当前为从右到左语言(如阿拉伯语、希伯来语)
}
`
#### 实战示例:Axios 拦截器
`ts
import axios from 'axios';
import { getLocale } from 'react-native-i18njs';
axios.interceptors.request.use((config) => {
// 动态获取当前语言,确保每次请求都携带最新的语言标识
config.headers['Accept-Language'] = getLocale();
return config;
});
`
当翻译内容中包含样式或组件时,使用 Trans 组件:
`tsx
import { Trans } from 'react-native-i18njs';
import { Text } from 'react-native';
// 翻译资源:
// zh: { agreement: '我同意 服务条款' }
components={{
link:
}}
/>
`
适用于大型应用的分包加载场景:
`ts
import { loadTranslations } from 'react-native-i18njs';
// 异步加载法语包
async function loadFrench() {
const fr = await import('./locales/fr');
loadTranslations({ fr: fr.default });
}
`
利用 Intl 标准进行格式化,在组件中通过 Hook 使用:
`ts
const { formatNumber, formatCurrency, formatDate } = useI18n();
// 数字
formatNumber(1234.56); // "1,234.56"
// 货币
formatCurrency(99.99, 'USD'); // "$99.99"
// 日期
formatDate(new Date(), { dateStyle: 'full' }); // "Tuesday, October 10, 2023"
`
在非组件环境中,也可以直接使用顶层导出:
`ts
import { formatNumber, formatCurrency, formatDate } from 'react-native-i18njs';
formatNumber(1234.56);
formatCurrency(99.99, 'USD');
formatDate(new Date());
`
initI18n 接受的第二个参数对象:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| defaultLocale | string | 'en' | 默认语言 |enableFallback
| | boolean | true | 是否启用回退机制 |followSystem
| | boolean | true | 是否初始化时自动跟随系统语言 |fallbackLocales
| | string[] \| func | - | 自定义回退链 |missingBehavior
| | 'key' \| 'empty' \| 'throw' | 'key' | 缺失翻译时的行为 |onMissingKey
| | function | - | 缺失 key 的回调 |onLocaleChange
| | function | - | 语言变更回调 |
时传入了你的翻译类型定义。$3
请确保你的 android/app/src/main/res 目录下有对应的语言资源文件夹(如 values-zh`),React Native 有时依赖这些原生配置来正确识别系统语言。ISC