【问题标题】:React native - Data fetch from Async storage before rendering the app componentReact native - 在渲染应用程序组件之前从异步存储中获取数据
【发布时间】:2020-03-12 12:06:13
【问题描述】:

我正在 React Native 上创建一个 iOS 应用程序,并希望该应用程序支持多语言。 该应用程序在设置目标语言时可以工作,但是当我再次打开该应用程序时,它会显示默认语言。我正在尝试从异步存储中获取定义的语言,但它不反映更改并呈现应用程序组件。我使用上下文 api 进行本地化。

我使用 Launchscreen.xib 来显示初始屏幕,并在 app.js useEffect 挂钩中使用 react-native-splash-screen 方法 SplashScreen.hide() 隐藏此初始屏幕,我想在加载之前设置之前选择的语言应用组件。

Localization.js 文件 -

import React, {createContext, useState} from 'react';
import * as RNLocalize from 'react-native-localize';
import LocalizedStrings from 'react-native-localization';
import AsyncStorage from '@react-native-community/async-storage';
import en from './translations/en.json';
import de from './translations/de.json';
import bg from './translations/bg.json';
import it from './translations/it.json';
import nl from './translations/nl.json';
import pl from './translations/pl.json';
import pt from './translations/pt.json';
import ru from './translations/ru.json';
import fr from './translations/fr.json';
import es from './translations/es.json';



const APP_LANGUAGE = 'appLanguage';
const DEFAULT_LANGUAGE = 'en';



const languages = {en, de, bg, it, nl, pl, pt, ru, fr, es};

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);
   //console.log(appLanguage);
    const setLanguage = language => {
      translations.setLanguage(language);
      setAppLanguage(language);
      AsyncStorage.setItem(APP_LANGUAGE, language);
    };

    const initializeAppLanguage = async () => {
      const currentLanguage = await AsyncStorage.getItem(APP_LANGUAGE);
      console.log('language' , currentLanguage);
      if (currentLanguage === null) {
        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);
      } else {
        setLanguage(currentLanguage);
      }
      onSuccess();
    };

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

App.js 文件

import React, {useEffect, useContext, useState} from 'react';
import {createStore, combineReducers, applyMiddleware} from 'redux';
import {composeWithDevTools} from 'redux-devtools-extension';
import {Provider} from 'react-redux';
import logger from 'redux-logger';
import ReduxThunk from 'redux-thunk';

import loginReducer from '_store/reducers/login.js';
import transportReducer from '_store/reducers/transport.js';
import gpsReducer from '_store/reducers/gpslogger.js';

import AppNavigator from '_navigations/AppNavigator';

import SplashScreen from 'react-native-splash-screen';
import FlashMessage from 'react-native-flash-message';
import {LocalizationContext} from './Localization';


const rootReducer = combineReducers({
  auth: loginReducer,
  transport: transportReducer,
  gps:  gpsReducer
});

const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(logger, ReduxThunk)));

const App = props => {
  const {initializeAppLanguage, appLanguage} = useContext(LocalizationContext);
  const [loaded, setLoaded] = useState(false);
  useEffect(() => {
    initializeAppLanguage();
    SplashScreen.hide();


  }, []);

  return (
   <Provider store={store}>

      <AppNavigator />

      <FlashMessage />
    </Provider>
  );
};

export default App;

我怎样才能实现所需的行为?

【问题讨论】:

    标签: javascript react-native localization


    【解决方案1】:

    我通过创建一个单独的初始屏幕并在那里放置一个 setTimeout 方法来解决它。它有时间从异步存储中获取数据,然后导航到主应用程序。

    【讨论】:

      【解决方案2】:

      我们正在做某事以在app.js 中实现相同的期望行为

      setI18nConfig = () => {
          const {dispatch} = this.store;
          const translationGetters = {
            ar: () => require("../src/assets/translations/ar.json"),
            en: () => require("../src/assets/translations/en.json"),
          };
      
          const translate = helpers.translate();
      
          const fallback = { languageTag: "en", isRTL: false };
      
          const { languageTag, isRTL } = this.appLanguage ?  this.appLanguage  : (RNLocalize.findBestAvailableLanguage(Object.keys(translationGetters)) || fallback)
      
          dispatch(setAppLanguage({
            languageTag,
            isRTL
          }));
      
          if(!this.appLanguage) {
            this.appLanguage = {languageTag, isRTL}
          }
      
          // clear translation cache
          translate.cache.clear();
      
          // set i18n-js config
          i18n.translations = { [languageTag]: translationGetters[languageTag]() };
          i18n.locale = languageTag;
        }
      

      【讨论】:

      • 您好,Rowan,感谢您的快速回复。我有几个问题。 1. 这个助手是从哪里来的? 2. 你是在 app.js 的 useEffect() 钩子中调用这个函数吗 3. 为了翻译所有的页面,你是使用 context api 还是仅仅这个就够了?谢谢!!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-01
      • 2017-01-06
      • 1970-01-01
      • 2018-09-03
      • 2016-08-02
      • 2020-09-13
      • 1970-01-01
      相关资源
      最近更新 更多