React Native项目中react-i18next翻译未生效问题求助
React Native + react-i18next 翻译未生效问题
我新建了一个React Native项目,使用react-i18next实现国际化,但翻译未生效,页面始终显示翻译键名且无任何报错;同时发现组件加载顺序早于layout.tsx。以下是相关配置与代码:
package.json依赖
{ (...) "dependencies": { "@expo/vector-icons": "^14.0.2", "@react-navigation/native": "^6.0.2", "expo": "~51.0.18", "expo-constants": "~16.0.2", "expo-font": "~12.0.7", "expo-linking": "~6.3.1", "expo-router": "~3.5.17", "expo-splash-screen": "~0.27.5", "expo-status-bar": "~1.12.1", "expo-system-ui": "~3.0.7", "expo-web-browser": "~13.0.3", "i18next": "^23.11.5", "i18next-browser-languagedetector": "^8.0.0", "i18next-http-backend": "^2.5.2", "react": "18.2.0", "react-dom": "18.2.0", "react-i18next": "^14.1.2", "react-native": "0.74.3", "react-native-gesture-handler": "~2.16.1", "react-native-reanimated": "~3.10.1", "react-native-safe-area-context": "4.10.1", "react-native-screens": "3.31.1", "react-native-web": "~0.19.10" }}
i18n配置文件
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import LanguageDetector from 'i18next-browser-languagedetector'; import en from '../assets/locales/translation_en_US.json'; import fr from '../assets/locales/translation_fr_FR.json'; import { LangCode } from './LanguageUtils'; const resources = { en: { translation: en, }, fr: { translation: fr, }, }; const initalizeI18Next = () => { console.log("🚀 ~ initalizeI18Next ~ resources:", resources); i18n .use(initReactI18next) .use(LanguageDetector) .init({ supportedLngs: [LangCode.en, LangCode.fr], debug: false, resources, lng: LangCode.en, fallbackLng: LangCode.fr, compatibilityJSON: 'v3', interpolation: { escapeValue: false, }, }); }; export default { initalizeI18Next };
翻译JSON文件(translation_en_US.json)
{ "welcome": "Welcome!", "step_1": "Step 1: Try it", "step_2": "Step 2: Explore", "step_3": "Step 3: Get a fresh start", "login": "Login", "edit_file": "Edit", "to_see_changes": "to see changes.", "press_to_open_dev_tools": "Press to open developer tools.", "explore_tab_info": "Tap the Explore tab to learn more about what's included in this starter app.", "run_command_reset_project": "When you're ready, run", "to_get_fresh_app_dir": "to get a fresh", "this_will_move_current_app": "directory. This will move the current", "to_app_example": "to" }
ThemedText组件实现
import React, { ReactNode, cloneElement, isValidElement } from 'react'; import { Text, type TextProps, StyleSheet } from 'react-native'; import { useTranslation } from 'react-i18next'; import { useThemeColor } from '@/hooks/useThemeColor'; export type ThemedTextProps = TextProps & { lightColor?: string; darkColor?: string; type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link'; translate?: boolean; }; export function ThemedText({ style, lightColor, darkColor, type = 'default', translate = true, ...rest }: ThemedTextProps) { const { t } = useTranslation(); const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text'); const translateChildren = (children: ReactNode): ReactNode => { if (typeof children === 'string') { return translate ? t(children) : children; } if (Array.isArray(children)) { return React.Children.map(children, translateChildren); } if (isValidElement(children)) { return cloneElement(children, { ...children.props, children: translateChildren(children.props.children), }); } return children; }; const translatedChildren = translateChildren(rest.children); return ( <Text style={[ { color }, type === 'default' ? styles.default : undefined, type === 'title' ? styles.title : undefined, type === 'defaultSemiBold' ? styles.defaultSemiBold : undefined, type === 'subtitle' ? styles.subtitle : undefined, type === 'link' ? styles.link : undefined, style, ]} {...rest} > {translatedChildren} </Text> ); } const styles = StyleSheet.create({ default: { fontSize: 16, lineHeight: 24, }, defaultSemiBold: { fontSize: 16, lineHeight: 24, fontWeight: '600', }, title: { fontSize: 32, fontWeight: 'bold', lineHeight: 32, }, subtitle: { fontSize: 20, fontWeight: 'bold', }, link: { lineHeight: 30, fontSize: 16, color: '#0a7ea4', }, });
补充说明
直接在组件中调用t('welcome')的方式有效:
import { StyleSheet } from 'react-native'; import { HelloWave } from '@/components/HelloWave'; import { ThemedText } from '@/components/ThemedText'; import { ThemedView } from '@/components/ThemedView'; import { useTranslation } from 'react-i18next'; export default function HomeScreen() { const { t } = useTranslation(); return ( <ThemedView style={styles.titleContainer}> {t('welcome')} <HelloWave /> </ThemedView> ); } const styles = StyleSheet.create({ titleContainer: { flexDirection: 'row', alignItems: 'center', gap: 8, }, stepContainer: { gap: 8, marginBottom: 8, }, reactLogo: { height: 178, width: 290, bottom: 0, left: 0, position: 'absolute', }, });
内容的提问来源于stack exchange,提问作者Dan M. CISSOKHO
相关产品推荐
相关产品推荐

