Monday, 25 January 2021

Updating React Native language by user choice

I'm using I18n to create multiple language application.

I have created "on first launch" screen that offers the user option to choose his preferred language, it works fine but there is problem.

Once I choose language, App() component updates, it showing login component (initialRouteName="Login"). But the language is still by default English, only when I proceed to another screen it works or either FastRefresh login screen.

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= initialRouteName="Login">
        <Stack.Screen name="Login" component={Login} />
        <Stack.Screen name="Register" component={Register} />
        <Stack.Screen name="Dashboard" component={Dashboard} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

I wonder since I have updated my component, the language should update as well, isn't?

Here are some screenshots that will visually explain what my problem is.

enter image description here enter image description here enter image description here

How can I update React Native app by user choice using I18n plugin?

EDIT

Debugging results:

selectedLaunched(value) - value returns boolean value correctly.

Checking setAppLaunched(en) if statement to see if responding correctly, it does.

selected state is also working fine and rendering the NavigationContainer component right after it set to true.



from Updating React Native language by user choice

No comments:

Post a Comment