使用 Expo 在 React Native 中进行 i18n
Github 上的项目
为了使本文更加全面,我创建了一个包含真实应用程序的仓库,您可以在其中分析代码并查看所提及示例的完整实现。请访问 GitHub 上的仓库:app-internationalization。
首先,安装库
您需要安装 react-i18next、i18next 和 expo-localization 所需的库。
npx expo install expo-localization react-i18next i18next
本例中我使用了 AsyncStorage,因此您也需要安装它。如果您使用其他解决方案来持久化数据,请自行替换。
npx expo install @react-native-async-storage/async-storage
现在,在 src 目录中创建配置文件。创建一个名为的文件,./i18n/index.ts
内容如下:
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import * as Localization from "expo-localization";
import AsyncStorage from "@react-native-async-storage/async-storage";
import translationEn from "./locales/en-US/translation.json";
import translationPt from "./locales/pt-BR/translation.json";
import translationZh from "./locales/zh-CN/translation.json";
const resources = {
"pt-BR": { translation: translationPt },
"en-US": { translation: translationEn },
"zh-CN": { translation: translationZh },
};
const initI18n = async () => {
let savedLanguage = await AsyncStorage.getItem("language");
if (!savedLanguage) {
savedLanguage = Localization.locale;
}
i18n.use(initReactI18next).init({
compatibilityJSON: "v3",
resources,
lng: savedLanguage,
fallbackLng: "pt-BR",
interpolation: {
escapeValue: false,
},
});
};
initI18n();
export default i18n;
在此示例中,我使用 AsyncStorage 来持久化国际化数据,以防用户手动更改语言。此外,还使用 expo-localization 配置来获取设备当前语言。
在根应用程序中导入 i18n 文件
“我在 中使用它_layout.tsx
,但如果您的根文件是index.ts
或其他文件,则需要将其导入该根文件中。”在根应用程序的
文件中导入的示例:_layout.tsx
import { useEffect } from 'react';
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
import { useFonts } from 'expo-font';
import { Stack } from 'expo-router';
import * as SplashScreen from 'expo-splash-screen';
import 'react-native-reanimated';
import '@/i18n'; // This line imports the i18n configuration
import { useColorScheme } from '@/hooks/useColorScheme';
export default function RootLayout() {
const colorScheme = useColorScheme();
const [loaded] = useFonts({
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
});
useEffect(() => {
if (loaded) {
SplashScreen.hideAsync();
}
}, [loaded]);
if (!loaded) {
return null;
}
return (
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="+not-found" />
</Stack>
</ThemeProvider>
);
}
现在您需要创建翻译文件并在组件中使用它们。
为翻译的语言环境创建文件
在 i18n 文件夹中,创建一个名为locales的文件夹。在locales文件夹中,为每个语言环境(例如en-US、pt-BR或zh-CN )创建子文件夹。在每个子文件夹中,创建一个以您的翻译条目命名的 JSON 文件translation.json
。以下是这些 JSON 文件的示例。
命名文件:./i18n/locales/en-US/translation.json
{
"language": "Language",
"home": {
"title": "Home",
"welcome": "Welcome",
"subtitle": "Example i18n App!",
"description": "This is an example React Native application demonstrating how to implement internationalization (i18n) using react-i18next. The app allows users to switch between different languages for a more localized experience.",
"exploringLanguages": "Exploring Languages",
"exploringLanguagesDescription": "Click on country flags to explore the app's content in different languages.",
"learnMore": "Want to Learn More?",
"repositoryLinkText": "Project repository on GitHub",
"articlesLinkText": "More articles"
},
"features": {
"title": "Features",
"collapsibles": {
"i18n": {
"title": "Internationalization with i18next",
"description": "Uses react-i18next for language management, allowing the app to be localized for different languages."
},
"persistent": {
"title": "Persistent Language Selection",
"description": "Uses AsyncStorage to persistently store the user's preferred language, providing a consistent experience across app restarts."
},
"fallback": {
"title": "Language Fallback",
"description": "Defaults to the device's language if no language preference is saved."
},
"switching": {
"title": "Easy Language Switching",
"description": "Users can switch languages by tapping on country flags."
}
}
}
}
命名文件:./i18n/locales/pt-BR/translation.json
{
"language": "Idioma",
"home": {
"title": "Início",
"welcome": "Bem-vindo",
"subtitle": "App de Exemplo com i18n!",
"description": "Este é um exemplo de aplicativo React Native que demonstra como implementar internacionalização (i18n) usando react-i18next. O aplicativo permite aos usuários alternar entre diferentes idiomas para uma experiência mais localizada.",
"exploringLanguages": "Explorando Idiomas",
"exploringLanguagesDescription": "Clique nas bandeiras dos países para explorar o conteúdo do aplicativo em diferentes idiomas.",
"learnMore": "Quer Saber Mais?",
"repositoryLinkText": "O repositório do projeto no GitHub",
"articlesLinkText": "Mais artigos"
},
"features": {
"title": "Funcionalidades",
"collapsibles": {
"i18n": {
"title": "Internacionalização com i18next",
"description": "Utiliza react-i18next para gerenciamento de idiomas, permitindo que o aplicativo seja localizado para diferentes idiomas."
},
"persistent": {
"title": "Seleção de Idioma Persistente",
"description": "Utiliza AsyncStorage para armazenar persistentemente o idioma preferido do usuário, proporcionando uma experiência consistente ao reiniciar o aplicativo."
},
"fallback": {
"title": "Fallback de Idioma",
"description": "Padrão para o idioma do dispositivo se nenhuma preferência de idioma for salva."
},
"switching": {
"title": "Troca Fácil de Idioma",
"description": "Os usuários podem trocar de idioma tocando nas bandeiras dos países."
}
}
}
}
命名文件:./i18n/locales/zh-CN/translation.json
{
"language": "语言",
"home": {
"title": "开始",
"welcome": "欢迎",
"subtitle": "i18n示例应用!",
"description": "这是一个使用react-i18next实现国际化(i18n)的React Native示例应用。该应用允许用户在不同语言之间切换,以提供更本地化的体验。",
"exploringLanguages": "探索语言",
"exploringLanguagesDescription": "点击国家旗帜以在不同语言下探索应用内容。",
"learnMore": "想了解更多?",
"repositoryLinkText": "GitHub上的项目仓库",
"articlesLinkText": "更多文章"
},
"features": {
"title": "功能",
"collapsibles": {
"i18n": {
"title": "使用i18next进行国际化",
"description": "使用react-i18next进行语言管理,使应用程序能够在不同语言环境下本地化。"
},
"persistent": {
"title": "持久化语言选择",
"description": "使用AsyncStorage持久化存储用户的首选语言,提供应用重启后的一致体验。"
},
"fallback": {
"title": "语言回退
",
"description": "如果未保存语言首选项,则默认使用设备的语言。"
},
"switching": {
"title": "简便的语言切换",
"description": "用户可以通过点击国家旗帜来切换语言。"
}
}
}
}
太棒了!现在您有了英语、葡萄牙语和中文的翻译文件。
在组件中使用你的翻译
现在,您需要在组件中使用翻译,并使用useTranslation钩子创建一个用于更改语言环境的标志列表。
// import hook
import { useTranslation } from "react-i18next";
// inside a component
const { t } = useTranslation();
const text = t('example.text');
真实组件中基本用法的示例:
import React, { useEffect } from "react";
import { StyleSheet, View, ScrollView, TouchableOpacity } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { ThemedText } from "@/components/ThemedText";
import { useTranslation } from "react-i18next";
import Brasil from "./flags/Brasil";
import USA from "./flags/USA";
import China from "./flags/China";
const flags = [
{ component: Brasil, lang: "pt-BR", name: "Brasil" },
{ component: USA, lang: "en-US", name: "USA" },
{ component: China, lang: "zh-CN", name: "China" },
];
export function Language() {
const { i18n, t } = useTranslation();
const currentLanguage = i18n.language;
useEffect(() => {
const loadLanguage = async () => {
const savedLanguage = await AsyncStorage.getItem("language");
if (savedLanguage) {
i18n.changeLanguage(savedLanguage);
}
};
loadLanguage();
}, [i18n]);
const changeLanguage = async (lang: string) => {
await AsyncStorage.setItem("language", lang);
i18n.changeLanguage(lang);
};
return (
<View style={styles.container}>
<ThemedText style={styles.text}>{t('language')}</ThemedText>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.flagsContainer}
>
{flags.map(({ component: Flag, lang, name }) => (
<TouchableOpacity
key={name}
onPress={() => changeLanguage(lang)}
style={[
styles.flag,
currentLanguage === lang && styles.activeFlag,
currentLanguage !== lang && styles.inactiveFlag,
]}
>
<Flag width={45} height={45} />
</TouchableOpacity>
))}
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
justifyContent: "center",
},
flagsContainer: {
flexDirection: "row",
paddingVertical: 10,
},
flag: {
paddingHorizontal: 10,
},
activeFlag: {
transform: [{ scale: 1.2 }],
},
inactiveFlag: {
opacity: 0.5,
},
text: {
fontSize: 22,
lineHeight: 32,
marginTop: -6,
},
});
大功告成!现在你拥有了一个支持多种语言国际化的 React Native 应用,可供世界各地的用户使用。祝你编程愉快,享受你的 #hacktoberfest 吧!
参考
如果您需要参考,请查看以下链接以获取更多示例:
- GitHub上的应用程序实现源代码
- 我的 LinkedIn 个人资料:Lucas Ferreira Lima
- 我在 GitHub 上的个人资料:@lucasferreiralimax
- 官方网站:react-i18next
- React Native:reactnative.dev
- 博览会:expo.dev
需要幫忙?
欢迎评论或联系我。我很乐意帮忙,很高兴认识你。
文章来源:https://dev.to/lucasferreiralimax/i18n-in-react-native-with-expo-2j0j