Как правильно использовать хук useContext для переводов в React-Native - PullRequest
0 голосов
/ 06 марта 2020

React-хуки для меня довольно новы, и в настоящее время я сталкиваюсь с проблемой, когда экран запуска моего приложения не переведен. Я использовал этот блог pos , чтобы настроить провайдера и создать контекст для моих переводов. Это привело к тому, что компонент, показанный ниже:

import NL from '../translations/nl.json';
import GB from '../translations/en.json';
import * as RNLocalize from 'react-native-localize';
import React, { createContext, useState } from 'react';
import LocalizedStrings from 'react-native-localization';
import AsyncStorage from '@react-native-community/async-storage';

const DEFAULT_LANGUAGE = 'NL';
const APP_LANGUAGE= 'appLanguage';

const languages = {GB, NL};
const translations = new LocalizedStrings(languages);

export const LocalizationContext = createContext({
   translations,
   setAppLanguage: () => {},
   appLanguage: DEFAULT_LANGUAGE,
   initializeAppLanguage: () =>{},
});

export const LocalizationProvider = ({children}) => {
    const [appLanguage, setAppLanguage] = useState(DEFAULT_LANGUAGE);

    const setLanguage = language => {
        translations.setLanguage(language);
        setAppLanguage(language);

        AsyncStorage.setItem(APP_LANGUAGE, language);
    }

    const initializeAppLanguage = async () => {
        const currentLanguage = await AsyncStorage.getItem(APP_LANGUAGE);

        if (currentLanguage) {
            setLanguage(currentLanguage);
        } else {
            let localeCode = DEFAULT_LANGUAGE;
            const supportedLocaleCodes = translations.getAvailableLanguages();
            const phoneLocaleCodes = RNLocalize.getLocales().map(
                locale => locale.languageCode,
            );

            phoneLocaleCodes.some(code => {
                if(supportedLocaleCodes.includes(code)) {
                    localeCode = code;
                    return true;
                }
            });

            setLanguage(localeCode)
        }
    };

    return (
        <LocalizationContext.Provider
            value={{
                translations,
                setAppLanguage: setLanguage,
                appLanguage,
                initializeAppLanguage
            }}>
            {children}
        </LocalizationContext.Provider>
    )
}

Но, что бы я ни пытался, я не смогу правильно настроить первый экран при первом отображении экрана. Каждый раз, когда мой код обновляется (например, просто нажав «Сохранить» в моем редакторе), переводы отображаются правильно. Ниже я поделюсь кодом моего экрана. Я даже пытался использовать хук useEffect и вызывать метод setLanguage с языком, сохраненным в AsyncStorage в качестве параметра. Я также использую этот метод на экране выбора языка, где он работает правильно. Любые советы о том, как преодолеть эту проблему, с благодарностью.

import React, { useContext, useEffect } from 'react';
import { View } from 'react-native';
import Video from 'react-native-video'
import { useDispatch } from 'react-redux';
import { Styles } from './AuthScreenStyle';
import { Image } from 'react-native-elements';
import { Button } from '../../components/StyledButtons';
import { STORAGE_HELPER } from '../../helpers/AsyncStorageHelper';
import { USER_DB_HELPER } from '../../database/UserDatabaseHelper';
import { LocalizationContext } from '../../components/Translations';

const AuthScreen = ({navigation}) => { 
   const { translations, initializeAppLanguage } = useContext(LocalizationContext);
   const dispatch = useDispatch();
   initializeAppLanguage()

    return (
        <View style={Styles.container}>
            <Video
                repeat={true}
                resizeMode={'cover'}
                style={Styles.backgroundVideo}
                source={require('../../assets/videos/video.mp4')} />

            <View style={Styles.overlay}/>

            <View style={Styles.logoContainer}>
                <Image
                    style={Styles.logo}
                    source={require('../../assets/images/logo.png')} />
            </View>

            <View style={Styles.buttonContainer}>
                <Button 
                    title={translations['auth.login_title']}
                    onPress={() => navigation.navigate('SignIn')} />
             </View>
         </View>
    )
}

AuthScreen.navigationOptions={
    headerShown: false
}

export default AuthScreen
...