react-native-i18n icon indicating copy to clipboard operation
react-native-i18n copied to clipboard

Updating I18n language config on first launch

Open yotamdahan opened this issue 3 years ago • 3 comments

I'm trying to set the app language by user choice on first app launch.

I have this stack overflow question, but no luck there.

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.clear()
  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 selectLaunched = (value) => {
    setAppLaunched(value);
    onSelect();
  };


  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);
      setSelected(hasLaunched != null);
    } catch (err) {
      setSelected(false);
    }
  };

  useEffect(() => verifyHasLaunched, []);

  if (!selected){
    return <CheckIfFirstLaunch onSelect={() => setSelected(true)} />;
  }
  else{
    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="Login">
        <Stack.Screen name="Login" component={Login} />
        <Stack.Screen name="Register" component={Register} />
        <Stack.Screen name="Dashboard" component={Dashboard} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

So far I have managed to display the first launch screen with 2 language options (Hebrew, English). After I choose language the app re-renders and the language remains as default. Only after I proceed to another screen/refresh the screen I can see the language change.

But the component has already re-rendered, so what can cause that?

yotamdahan avatar Jan 17 '21 17:01 yotamdahan

Same issue is appear to me as well, In my case I18n.locale get successfully updated but when I logged out & send user to Sign In screen at first render it is the new language but on second render it changes to default, don't know what's causing this behaviour

FayyazAliKhan1 avatar Mar 14 '22 11:03 FayyazAliKhan1

Same issue for me too, do you have any solution>??

atdhetwig avatar May 10 '22 14:05 atdhetwig