[英]React Native & i18n returns to default language after routing to another screen
我正在將 React Native 與 i18n 語言管理器一起使用,並且我正在嘗試在首次應用啟動時創建語言選擇。
語言選擇屏幕確實有效,在選擇語言后組件重新渲染並執行正確的語言。 (假設我選擇了英文,按鈕字符串是英文的)
但是登錄到應用程序后,語言發生了變化,我真的不明白為什么。 (這里假設是英文,而是顯示希伯來語字符串)
這是 App.js 文件,我使用Async Storage
檢查該應用程序之前是否已啟動(如果沒有顯示語言選擇,是否使用了保存的語言選擇)。
import React, {useEffect, useState} from "react";
import Login from "./login.js";
import Register from "./register.js";
import Dashboard from "./dashboard.js";
import i18n from "./translation.js";
import { NavigationContainer, useNavigation } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { Text, View, Button, I18nManager } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
const Stack = createStackNavigator();
const HAS_LAUNCHED = "hasLaunched";
const ENGLISH = "en";
const HEBREW = "he";
//Save the language as AsyncStorage for other times the user will open the app
async function setAppLaunched(en) {
AsyncStorage.setItem(HAS_LAUNCHED, "true");
AsyncStorage.setItem(en ? ENGLISH : HEBREW, "true");
if(await AsyncStorage.getItem(HEBREW)){
i18n.locale = "he";
I18nManager.forceRTL(true);
}
else{
i18n.locale = "en";
I18nManager.forceRTL(false);
}
}
//If first launch show this screen
function CheckIfFirstLaunch({ onSelect }) {
const navigation = useNavigation();
const selectLaunched = (value) => {
if(value){
i18n.locale = "en";
I18nManager.forceRTL(false);
}
else{
i18n.locale = "he";
I18nManager.forceRTL(true);
}
setAppLaunched(value);
onSelect();
navigation.navigate('Login');
};
return (
<View>
<Text>Choose Language</Text>
<Button onPress={() => selectLaunched(false)} title="Hebrew"/>
<Button onPress={() => selectLaunched(true)} title="English"/>
</View>
);
}
export default function App() {
const [selected, setSelected] = useState(false);
const verifyHasLaunched = async () => {
try {
const hasLaunched = await AsyncStorage.getItem(HAS_LAUNCHED);
console.log(await AsyncStorage.getItem(HAS_LAUNCHED));
if(hasLaunched){
setSelected(true);
}
else{
setSelected(false);
}
} catch (err) {
setSelected(false);
}
};
useEffect(() => verifyHasLaunched, []);
if(selected){
const verifyLang = async () => {
const lang = await AsyncStorage.getItem('he');
if(lang != null){
i18n.locale = "he";
I18nManager.forceRTL(true);
}
else{
i18n.locale = "en";
I18nManager.forceRTL(false);
}
};
() => verifyLang;
}
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{headerShown: false}} initialRouteName={selected ? "Login" : "Language"}>
<Stack.Screen name="Language" >
{props => (<CheckIfFirstLaunch {...props} onSelect={() => setSelected(true)} />)}
</Stack.Screen>
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Register" component={Register} />
<Stack.Screen name="Dashboard" component={Dashboard} />
</Stack.Navigator>
</NavigationContainer>
);
}
翻譯.js
import i18n from 'i18n-js';
import en from './locale/en.json';
import he from './locale/he.json';
i18n.defaultLocale = 'en';
i18n.fallbacks = true;
i18n.translations = { en, he };
export default i18n;
我已經調試了AsyncStorage
中的值並收到了正確的值。
看起來, Async Storage
保存了重新渲染App.js
文件的語言數據,但 I18n 在屏幕路由后重置了他的設置。 這是為什么?
如何在第一次使用 React Native 啟動應用程序時為整個應用程序設置語言?
我已經分叉了你的沙箱https://codesandbox.io/s/xenodochial-mclean-ctk5p?file=/src/App.js
有幾個變化。
問題來自這樣一個事實,即每次您選擇一種語言時,您都將其設置為存儲中的鍵。
一旦您選擇了英語,重新加載並選擇了希伯來語,您就可以像這樣在存儲中獲得兩個鍵
{'he': true, 'en': true}
在這一點上,這部分總是將 lang 設置為希伯來語,因為確實有這樣的鍵(“他”是真的)。
const verifyLang = async () => {
const lang = await AsyncStorage.getItem('he');
if(lang != null){
i18n.locale = "he";
I18nManager.forceRTL(true);
}
我改變的是我們不再將每種語言都設置為鍵。 相反,我們通過selectLaunched
傳遞語言本身。 然后我們將它保存在存儲中的lang
鍵中。 這樣, lang
鍵始終存儲正確的語言 - 'he' 或 'en'。
verifyLang
可以刪除,因為它不再需要。 希望這能解決您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.