Я новичок в React Native и пытаюсь понять, как функция, написанная в родительском Компоненте, может передаваться (наследоваться) любым дочерним и дочерним элементам. В частности, я использую библиотеку для интернационализации своего приложения, используя:
import * as RNLocalize from 'react-native-localize'
import i18n from 'i18n-js'
Но я заметил, что мне нужно реализовать функцию translate(...)
для каждого компонента всего проекта, и это кажется преувеличенным, потому что это требует много работы для реализации функции перевода (я следовал этого урока ).
Обратите внимание, что у меня есть базовое c понимание того, как передать функцию или некоторые данные, используя this.props , поэтому я не спрашиваю, как props работает от родителя к одному ребенку. Я спрашиваю: как избежать повторения кода от //BEGIN ...
до //END...
(см. Файл WithSecurityScreen) и чтобы избежать повторения реализации handleLocalizationChange , RNLocalize.addEventListener , RNLocalize.removeEventListener и translate .
Также обратите внимание, что библиотека перевода работает, тест предоставляется на следующей строке WithSecurityScreen:
const SecurityScreen = () => <View><Text>{translate('USER_SURNAME')}?</Text></View>;
Но я не могу передать функцию translate (...) каждому компоненту всего проекта.
Структура проекта:
- Приложение. js (оборачивает SecureApp. js)
- SecureApp. js (оборачивается в приложение. js и запускается WithSecurityScreen. js)
- WithSecurityScreen . js (перенос маршрутов к видам, например, Welcome. js)
- Welcome. js (основной вид)
Приложение. 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);
WithSecurityScre EN. 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;
Добро пожаловать. 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>
);
}
}
Я получаю следующую ошибку: