如何在React Native中使用Navigator和WithSecurityScreen将功能从父级传递给任何子级和子级子代?

问题描述 投票:0回答:2

我在React Native中还很陌生,我试图了解如何将父组件中编写的函数传递(继承)给任何子代和子代子代。特别是,我正在使用以下库来国际化我的App:

import * as RNLocalize from 'react-native-localize'
import i18n from 'i18n-js'

但是我注意到我必须为整个项目的每个组件实现translate(...)函数,并且这似乎被夸大了,因为实现翻译功能需要很多工作(我遵循this tutorial)。

请注意,我对如何使用this.props传递函数或某些数据有基本的了解,所以我不问props是如何从父母到一个孩子的。我要问的是:如何避免从//BEGIN ...//END...重复代码(请参阅WithSecurityScreen文件),以及避免重复执行handleLocalizationChangeRNLocalize.addEventListener,< [RNLocalize.removeEventListener和translate

请注意,翻译库可以正常工作,在WithSecurityScreen的以下行提供了测试:

const SecurityScreen = () => <View><Text>{translate('USER_SURNAME')}😂</Text></View>;

但是我无法将

translate(...)

函数传递给整个项目的每个组件。项目结构为:

    App.js(包装SecureApp.js)
  • SecureApp.js(包装在App.js中并运行WithSecurityScreen.js)
  • WithSecurityScreen.js(将路径包装到视图,例如Welcome.js)
  • Welcome.js(主视图)
  • App.js

  • import { withSecurityScreen } from './src/components/withSecurityScreen' import App from "./SecureApp.js" export default withSecurityScreen(App);

    SecureApp.js

    const MainNavigator = createStackNavigator({ Home: { screen: Welcome, navigationOptions: { headerShown: false } }, UserProfile: { screen: CoreApp, navigationOptions: { headerShown: false } }, NumPad: { screen: NumPad, navigationOptions: { header: 'PIN Creation', headerShown: false } }, /* , navigationOptions: {headerLeft: () => null} */ QrScan: { screen: QrScan, navigationOptions: { header: 'QR Scan', headerShown: false } }, ... }); export default createAppContainer(MainNavigator);

    WithSecurityScreen.js

    // START: https://heartbeat.fritz.ai/how-to-use-react-native-localize-in-react-native-apps-3bb3d510f801 import * as RNLocalize from 'react-native-localize' import i18n from 'i18n-js' import memoize from 'lodash.memoize' const translationGetters = { en: () => require('./../../assets/locales/en/en.json'), it: () => require('./../../assets/locales/it/it.json') }; const translate = memoize( (key, config) => i18n.t(key, config), (key, config) => (config ? key + JSON.stringify(config) : key) ) const setI18nConfig = () => { const fallback = { languageTag: 'en' } const { languageTag } = RNLocalize.findBestAvailableLanguage(Object.keys(translationGetters)) || fallback translate.cache.clear() i18n.translations = { [languageTag]: translationGetters[languageTag]() } i18n.locale = languageTag } // END: https://heartbeat.fritz.ai/how-to-use-react-native-localize-in-react-native-apps-3bb3d510f801 const SecurityScreen = () => <View><Text>{translate('USER_SURNAME')}😂</Text></View>; const showSecurityScreenFromAppState = appState => ['background', 'inactive'].includes(appState); const withSecurityScreenIOS = Wrapped => { return class WithSecurityScreen extends React.Component { constructor(props) { super(props) setI18nConfig() } state = { showSecurityScreen: showSecurityScreenFromAppState(AppState.currentState) }; componentDidMount() { AppState.addEventListener('change', this.onChangeAppState) RNLocalize.addEventListener('change', this.handleLocalizationChange) } componentWillUnmount() { AppState.removeEventListener('change', this.onChangeAppState) RNLocalize.removeEventListener('change', this.handleLocalizationChange) } handleLocalizationChange = () => { setI18nConfig() .then(() => this.forceUpdate()) .catch(error => { console.error(error) }) } onChangeAppState = nextAppState => { const showSecurityScreen = showSecurityScreenFromAppState(nextAppState); this.setState({showSecurityScreen}) }; render() { return this.state.showSecurityScreen ? <SecurityScreen/> : <Wrapped {...this.props} /> } } }; const withSecurityScreenAndroid = Wrapped => Wrapped; export const withSecurityScreen = Platform.OS === 'ios' ? withSecurityScreenIOS : withSecurityScreenAndroid;

    Welcome.js

    export default class Welcome extends Component { let username = 'UserName'; render() { return ( <View style={styles.container}> <LinearGradient colors={globalStyles.colors.gradientGreen} style={{flex: 1}}> <View style={styles.upperView}><Text style={styles.upperViewText}>{this.props.translate('WELCOME_TEXT')}{this.username}</Text> </View> </LinearGradient> </View> ); } }
    我收到以下错误:

    enter image description here

    react-native translation globalization
    2个回答
    0
    投票
    我使用import i18n from "i18next"进行翻译。这是配置文件:

    //config/i18n import i18n from "i18next"; import { reactI18nextModule, initReactI18next } from "react-i18next"; import translationFR from '../translation/fr/translation.json'; import translationEN from '../translation/en/translation.json'; import DeviceInfo from 'react-native-device-info'; let locale = DeviceInfo.getDeviceLocale().substring(0, 2); if (locale != 'fr') { locale = 'en'; } // the translations const resources = { en: translationEN, fr: translationFR, }; i18n .use(reactI18nextModule) // passes i18n down to react-i18next .init({ resources: resources, lng: locale, fallbackLng: ['en', 'fr'], keySeparator: false, // we do not use keys in form messages.welcome interpolation: { escapeValue: false // react already safes from xss } }); export default i18n;

    用途之一是

    import i18n from 'config/i18n'

    并使用像这样在文件中翻译

    i18n.t('bottomTab:home_tab')

    您还可以使用'react-i18next'中的withNamespaces包装组件,如下所示:

    export default withNamespaces([], {wait: true})(Welcome)

    然后访问翻译:

    this.props.t('welcome_message')


    0
    投票
    首先,在您的情况下,您可以在单独的js文件locale.js中声明翻译功能,并且可以在该文件中声明所有翻译逻辑并导出功能translatesetI18nConfig

    local.js

    import * as RNLocalize from 'react-native-localize' import i18n from 'i18n-js' import memoize from 'lodash.memoize' const translationGetters = { en: () => require('./../../assets/locales/en/en.json'), it: () => require('./../../assets/locales/it/it.json') }; export const translate = memoize( (key, config) => i18n.t(key, config), (key, config) => (config ? key + JSON.stringify(config) : key) ) export const setI18nConfig = () => { const fallback = { languageTag: 'en' } const { languageTag } = RNLocalize.findBestAvailableLanguage(Object.keys(translationGetters)) || fallback translate.cache.clear() i18n.translations = { [languageTag]: translationGetters[languageTag]() } i18n.locale = languageTag }
    并将此功能导入您想使用该功能的组件中

    App.js

    import React, { Component } from 'react'; import { View, Text } from 'react-native'; import { setI18nConfig, translate } from './locale'; export default class App extends Component { constructor(props) { super(props); this.state = {}; } render() { setI18nConfig(); // This should be called only once through out the app at the time of changing locale. return ( <View> <Text> translate ('key_from_json_to_label') </Text> </View> ); } }
    有关更多详细信息,您可以在我已经实现相同的位置refer this repo。>>

    希望这会有所帮助。

    © www.soinside.com 2019 - 2024. All rights reserved.