expo response-native реагировать-навигация response-intl, как запускать обновление сообщений после разрешения локали пользователя
Я использую expo, response-native, redux, реагировать-навигацию и реагировать-intl. Экспо имеет этот асинхронный Localization.getCurrentLocaleAsync()
функция для получения локали асинхронно. Я столкнулся с проблемой распространения изменений локали и сообщений вплоть до дочерних компонентов. Например, если я установил начальную локаль в es "Root.js", когда Localization.getCurrentLocaleAsync()
вставьте и установите для языка "en", обновленные сообщения не были отражены в дочернем компоненте "Login.js". Таким образом, симулятор выдает console.error: Missing message: "Login.login" for locale: "es", using default message as fallback
в то время как я обновил язык и сообщение в root.js
состояние Вот мой код:root.js
import React from 'react';
import { Provider } from 'react-redux';
import { StyleSheet, Text, View, Alert } from 'react-native';
import { DangerZone } from 'expo';
import { IntlProvider, addLocaleData, injectIntl } from 'react-intl';
import { createBottomTabNavigator, createSwitchNavigator } from 'react-navigation';
import { PersistGate } from 'redux-persist/integration/react';
import AuthLoadingPage from './containers/authLoading';
import LoginPage from './containers/login';
import SignupPage from './containers/signup';
import HomePage from './containers/home';
import NotFoundPage from './containers/notFound';
import configureStore from './configureStore';
import en from 'react-intl/locale-data/en';
import es from 'react-intl/locale-data/es';
import localeData from './build/data.json';
addLocaleData([...en, ...es]);
const { Localization } = DangerZone;
const { persistor, store } = configureStore();
const AuthTab = createBottomTabNavigator({
login: { screen: LoginPage },
signup: { screen: SignupPage },
},{
navigationOptions: {
tabBarVisible: false,
},
lazyLoad: true,
});
const MainNavigator = createSwitchNavigator({
authLoading: AuthLoadingPage,
main: { screen: HomePage},
auth: AuthTab,
},{
initialRouteName: 'authLoading',
});
class Root extends React.Component {
constructor(p) {
super(p);
this.state = {
currentLocale: 'es',
messages: localeData['es'],
};
}
componentDidMount() {
Localization.getCurrentLocaleAsync()
.then(currentLocale => {
console.log("currentLocale is >>>", currentLocale);
this.setState({
currentLocale,
messages: localeData[currentLocale],
});
});
}
render() {
console.log("this.state.message???", this.state.messages);
return (
<IntlProvider
locale={this.state.currentLocale}
key={this.state.currentLocale}
messages={this.state.messages}
textComponent={Text}
>
<Provider store={store}>
<PersistGate
loading={<NotFoundPage />}
onBeforeLift={() => {}}
persistor={persistor}
>
<MainNavigator />
</PersistGate>
</Provider>
</IntlProvider>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default Root;
и "Containers/Login.js":
import React, { Component } from 'react';
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import {
View,
Text,
TextInput,
Image,
Dimensions,
KeyboardAvoidingView,
StyleSheet,
Button,
TouchableOpacity
} from 'react-native';
import { FormLabel, FormInput } from 'react-native-elements';
import { authenticate } from '../modules/auth/actions';
const SCREEN_WIDTH = Dimensions.get('window').width;
class LoginPage extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: ''
};
}
handleSubmit(e) {
e.preventDefault();
const { email, password } = this.state;
const { navigation } = this.props;
this.props.dispatch(authenticate(email, password))
.then(() => {
navigation.navigate('main');
})
}
gotoSignup(e) {
e.preventDefault();
const { navigation } = this.props;
navigation.navigate('signup');
}
render() {
const { isAuthenticated, navigation } = this.props;
return (
<KeyboardAvoidingView behavior="padding" style={styles.container}>
<View style={styles.loginLogo}>
<FormattedMessage
id={ 'Login.login' }
defaultMessage={ 'Welcome to login screen!' }
/>
</View>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
width: Dimensions.get('window').width,
},
loginLogo: {
flex:1,
},
loginForm: {
flex: 2,
},
loginFormContainer: {
flex: 1,
padding: 20,
},
input: {
height: 40,
backgroundColor: 'rgba(255,255,255, 0.8)',
paddingLeft: 10,
marginBottom: 15,
},
buttoncontainer: {
backgroundColor: '#23618C',
marginTop: 10,
paddingVertical: 15,
},
buttontext: {
textAlign: 'center',
color: '#fff',
fontWeight: 'bold',
},
});
function mapStateToProps(state) {
const { auth } = state;
const { loading, isAuthenticated } = auth;
return {
loading,
isAuthenticated
};
}
export default connect(mapStateToProps)(LoginPage);
Вы также можете найти соответствующий код в github: root.js: https://github.com/7seven7lst/mobile-client-new/blob/master/root.js Containers / Login.js: https://github.com/7seven7lst/mobile-client-new/blob/master/containers/login.js
1 ответ
Не берите в голову. выше должно работать. Я испортил этот идентификатор. это должно быть "Login.Login", потому что это то, что у меня есть в data.json
файл.
<FormattedMessage
id={ 'Login.login' }
defaultMessage={ 'Welcome to login screen!' }
/>