使用 Expo 在 React Native 中进行 i18n

2025-06-07

使用 Expo 在 React Native 中进行 i18n

Github 上的项目

为了使本文更加全面,我创建了一个包含真实应用程序的仓库,您可以在其中分析代码并查看所提及示例的完整实现。请访问 GitHub 上的仓库:app-internationalization

图像应用程序-中文国际化巴西葡萄牙语和葡萄牙语图像应用程序国际化图像应用程序-英语国际化

首先,安装库

您需要安装 react-i18next、i18next 和 expo-localization 所需的库。



npx expo install expo-localization react-i18next i18next


Enter fullscreen mode Exit fullscreen mode

本例中我使用了 AsyncStorage,因此您也需要安装它。如果您使用其他解决方案来持久化数据,请自行替换。



npx expo install @react-native-async-storage/async-storage


Enter fullscreen mode Exit fullscreen mode

现在,在 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;


Enter fullscreen mode Exit fullscreen mode

在此示例中,我使用 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>
  );
}


Enter fullscreen mode Exit fullscreen mode

现在您需要创建翻译文件并在组件中使用它们。

为翻译的语言环境创建文件

在 i18n 文件夹中,创建一个名为locales的文件夹。在locales文件夹中,为每个语言环境(例如en-USpt-BRzh-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."
      }
    }
  }
}


Enter fullscreen mode Exit fullscreen mode

命名文件:./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."
      }
    }
  }
}


Enter fullscreen mode Exit fullscreen mode

命名文件:./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": "用户可以通过点击国家旗帜来切换语言。"
      }
    }
  }
}


Enter fullscreen mode Exit fullscreen mode

太棒了!现在您有了英语、葡萄牙语和中文的翻译文件。

在组件中使用你的翻译

现在,您需要在组件中使用翻译,并使用useTranslation钩子创建一个用于更改语言环境的标志列表。



// import hook
import { useTranslation } from "react-i18next";

// inside a component 
const { t } = useTranslation();
const text = t('example.text');



Enter fullscreen mode Exit fullscreen mode

真实组件中基本用法的示例:



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,
  },
});


Enter fullscreen mode Exit fullscreen mode

大功告成!现在你拥有了一个支持多种语言国际化的 React Native 应用,可供世界各地的用户使用。祝你编程愉快,享受你的 #hacktoberfest 吧!

参考

如果您需要参考,请查看以下链接以获取更多示例:

需要幫忙?

欢迎评论或联系我。我很乐意帮忙,很高兴认识你。

文章来源:https://dev.to/lucasferreiralimax/i18n-in-react-native-with-expo-2j0j
PREV
Vue.js 入门(速查表)
NEXT
ngrok 的快乐世界