react-native-i18njs
v1.0.1
Published
一个轻量级、类型安全、零心智负担的 React Native 国际化解决方案。
Maintainers
Readme
react-native-i18njs
一个极致轻量、类型安全、零心智负担的 React Native 国际化解决方案。
构建产物经 minify + gzip 后约 3.3 KB,对包体积几乎无感。
专为 React Native 设计,集成了最佳实践,解决繁琐配置、类型缺失、复杂 API 以及系统语言跟随等问题。
✨ 特性
- 📦 极小体积:ESM 构建 gzip 约 3.3 KB,CJS 约 3.5 KB;源码极致压缩,无冗余依赖。
- ✨ 零配置启动:内置智能默认值,安装即用。
- 🛡️ 极致类型安全:完全 TypeScript 编写,提供从 Key 到插值参数的完整类型推导。
- 📱 自动跟随系统:基于
react-native-localize,自动检测并响应设备语言变更。 - ⚡ 高性能:基于
i18n-js核心,轻量高效,无多余运行时开销。 - 🔌 灵活 API:同时支持 Hook (
useI18n)、高阶组件 (withI18n) 和全局函数 (t)。 - 📝 富文本支持:
Trans组件轻松处理嵌套样式和组件插值。 - 🌍 格式化内置:开箱即用的数字、货币、日期格式化支持。
📦 体积说明 (Bundle Size)
| 格式 | 未压缩 | gzip |
|------|--------|------|
| ESM (.mjs) | ~8.1 KB | ~3.3 KB |
| CJS (.js) | ~8.9 KB | ~3.5 KB |
以上为单入口打包、开启 minify 后的体积;实际打进业务的增量取决于打包工具的 tree-shaking。推荐使用 ESM 以获得更优体积与 gzip 表现。
📦 安装
npm install react-native-i18njs
# 或者
yarn add react-native-i18njs注意:
react-native-localize为 peer dependency,请确保项目中已安装:npm install react-native-localize
🚀 快速开始
1. 定义翻译资源
建议在单独的文件中管理翻译资源,例如 src/locales/index.ts:
// src/locales/index.ts
export const translations = {
en: {
welcome: 'Welcome',
hello: 'Hello, %{name}!',
},
zh: {
welcome: '欢迎',
hello: '你好,%{name}!',
},
};
// 导出类型以获得类型提示
export type Translations = typeof translations.en;2. 初始化
在你的 App 入口文件(如 App.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 以支持语言切换时的自动重渲染
<I18nProvider>
<Home />
</I18nProvider>
);
}3. 在组件中使用
// 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<Translations>();
return (
<View>
<Text>{t('welcome')}</Text>
{/* 这里的 name 参数会有类型提示 */}
<Text>{t('hello', { name: 'Trae' })}</Text>
<Text>当前语言: {locale}</Text>
<Button title="Switch to English" onPress={() => setLocale('en')} />
<Button title="切换到中文" onPress={() => setLocale('zh')} />
</View>
);
}📖 核心功能详解
1. 非组件环境使用(Global API)
在 Redux、Axios 拦截器、工具函数等非组件环境中,你可以直接使用全局导出的 API。
基础用法
import { t, getLocale, setLocale } from 'react-native-i18njs';
// 获取当前语言
const current = getLocale();
// 切换语言
setLocale('zh');
// 直接翻译
const message = t('errors.network_timeout');进阶:监听语言变化
如果你需要在组件外监听语言变更(例如同步更新全局状态),可以使用顶层 subscribe 函数:
import { subscribe } from 'react-native-i18njs';
// 订阅语言变更
const unsubscribe = subscribe((locale) => {
console.log('Language changed to:', locale);
// 更新 API 默认 Header 或其他全局状态
});
// 取消订阅
// unsubscribe();进阶:重置为跟随系统
用户手动调用 setLocale 后会锁定语言,不再自动跟随系统。如果需要恢复跟随系统语言:
import { resetToSystem } from 'react-native-i18njs';
// 撤销用户锁定,重新跟随系统语言
resetToSystem();进阶:RTL 检测
import { isRTL } from 'react-native-i18njs';
if (isRTL()) {
// 当前为从右到左语言(如阿拉伯语、希伯来语)
}实战示例:Axios 拦截器
import axios from 'axios';
import { getLocale } from 'react-native-i18njs';
axios.interceptors.request.use((config) => {
// 动态获取当前语言,确保每次请求都携带最新的语言标识
config.headers['Accept-Language'] = getLocale();
return config;
});2. 富文本翻译 (Trans 组件)
当翻译内容中包含样式或组件时,使用 Trans 组件:
import { Trans } from 'react-native-i18njs';
import { Text } from 'react-native';
// 翻译资源:
// zh: { agreement: '我同意 <link>服务条款</link>' }
<Trans
i18nKey="agreement"
components={{
link: <Text style={{ color: 'blue' }} onPress={openTerms} />,
}}
/>3. 动态加载翻译
适用于大型应用的分包加载场景:
import { loadTranslations } from 'react-native-i18njs';
// 异步加载法语包
async function loadFrench() {
const fr = await import('./locales/fr');
loadTranslations({ fr: fr.default });
}4. 格式化工具
利用 Intl 标准进行格式化,在组件中通过 Hook 使用:
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"在非组件环境中,也可以直接使用顶层导出:
import { formatNumber, formatCurrency, formatDate } from 'react-native-i18njs';
formatNumber(1234.56);
formatCurrency(99.99, 'USD');
formatDate(new Date());⚙️ 配置选项 (I18nOptions)
initI18n 接受的第二个参数对象:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| defaultLocale | string | 'en' | 默认语言 |
| enableFallback | boolean | true | 是否启用回退机制 |
| followSystem | boolean | true | 是否初始化时自动跟随系统语言 |
| fallbackLocales | string[] | func | - | 自定义回退链 |
| missingBehavior | 'key' | 'empty' | 'throw' | 'key' | 缺失翻译时的行为 |
| onMissingKey | function | - | 缺失 key 的回调 |
| onLocaleChange | function | - | 语言变更回调 |
✅ 生产就绪 (Production Ready)
本库在功能与健壮性上已按生产标准实现,具备:
| 能力 | 说明 |
|------|------|
| 多场景使用 | 组件内(Hook / HOC)、组件外(全局 t、格式化、Redux/拦截器等)统一 API |
| 插值与复数 | %{name} 插值、one/other 等复数规则(透传 i18n-js),支持 defaultValue |
| 缺失策略 | missingBehavior:回退 key / 空串 / 抛错;onMissingKey 便于上报与兜底 |
| 语言链 | 当前 locale 自动降级(如 en-US → en)、自定义 fallbackLocales、可函数动态回退 |
| 系统语言 | 基于 react-native-localize,App 回到前台自动同步;setLocale 用户锁定、resetToSystem 恢复跟随 |
| 动态文案 | loadTranslations 合并新语种/命名空间,subscribe 通知 UI 更新 |
| RTL | 按语言/script 检测 RTL,调用 I18nManager(需重启生效,属 RN 限制) |
| 格式化 | 数字/货币/日期使用 Intl 并带缓存,无 Intl 环境有降级 |
| 富文本 | Trans 支持标签解析、组件映射、插值内嵌 React 节点 |
| 类型安全 | Path<T>、useI18n<T> 提供 key 补全与校验 |
| 环境兼容 | 无 Intl / 无 react-native-localize 时 try-catch 降级,不抛错 |
使用前请在 App 入口先调用 initI18n,再使用 t / useI18n / Trans 等。
🧩 常见问题
使用前必须先 init 吗?
是的。在调用 t、useI18n、Trans 等之前,请在应用入口(如 App.tsx)执行一次 initI18n(translations, options),否则会使用空翻译表。
TypeScript 类型提示不工作?
确保你在使用 useI18n<MyTranslations>() 时传入了你的翻译类型定义。
安卓上语言检测不准确?
请确保你的 android/app/src/main/res 目录下有对应的语言资源文件夹(如 values-zh),React Native 有时依赖这些原生配置来正确识别系统语言。
📄 License
ISC
