一旦解决了用户区域设置,expo react-native react-navigation react-intl如何触发对消息的更新

时间:2018-09-23 15:03:42

标签: redux react-navigation expo react-intl

我正在使用expo,react-native,redux,react-navigation和react-intl。 Expo具有此异步Localization.getCurrentLocaleAsync()函数以异步检索语言环境。我在将语言环境和消息更改传播到子组件时遇到了问题。 例如,如果我在“ Root.js”中将初始语言环境设置为“ es”,则在插入Localization.getCurrentLocaleAsync()并将语言环境设置为“ en”时,更新的消息未反映在子组件“登录”中。 js”。这样,当我以Missing message: "Login.login" for locale: "es", using default message as fallback状态更新语言环境和消息时,模拟器会抛出console.error: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 container / Login.js:https://github.com/7seven7lst/mobile-client-new/blob/master/containers/login.js

1 个答案:

答案 0 :(得分:0)

没关系。以上应该工作。我把这个身份证弄乱了。它应该是“ Login.Login”,因为这就是我在data.json文件中所拥有的。

<FormattedMessage
   id={ 'Login.login' }
   defaultMessage={ 'Welcome to login screen!' }
/>