我开始了一个新的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 与翻译
{
"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"
}
我的实现
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',
},
});
编辑:
下面这个例子是有效的
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',
},
});
就我而言,不需要 useEffect 挂钩,我只需在主屏幕中使用
i18n.initalizeI18Next();