-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to change active locale programatically? #25
Comments
Are you using With const App = ({ currency, locale }) => (
<FormattedWrapper locale={locale} currency={currency} messages={Messages}>
<App />
</FormattedWrapper>
);
// Redux example
function mapStateToProps(state) {
return {
currency: state.currency,
locale: state.locale,
};
}
export default connect(mapStateToProps)(App); Basically you just need to update the locale and/or currency props on |
Thanks for the direction, it really help to fix the problem.
Maybe it can be put more nicely as I realize I'm not good enough with wrapping things up :) By the way, I was looking for a method like Thanks. |
Based on the example code you posted, your current locale is stored in your redux store. You could therefore easily make an action creator called |
@joshswan I have tried to archive the same as @willymulyana but even when I tried to switch my RootComponent to a const like your example, I couldn't get it to work. It only works if I add a FormattedWrapper in every component where I need to use the FormattedMessage. Here is the root component: ... //imports and styles
class RootContainer extends Component {
render() {
const locale = this.props.locale;
console.log("RootLocale",locale);
return (
<ThemeProvider theme={colors}>
<FormattedWrapper locale={locale} messages={messages}>
<Root>
<StatusBar barStyle='light-content' backgroundColor='transparent' translucent />
{ Platform.OS === 'android' && Platform.Version >= 20 ? <StatusBarAndroid /> : null }
<Navigator />
</Root>
</FormattedWrapper>
</ThemeProvider>
);
}
}
const mapStateToProps = (state) => ({
state,
locale: state.Language.language
});
const ConnectedRootContainer = connect(mapStateToProps,null)(RootContainer);
class App extends Component {
render() {
return (
<Provider store={store}>
<ConnectedRootContainer />
</Provider>
);
}
}
export default App; My locale is changed with Redux, and to show it, I have add a console.log to the RootComponent. As mentioned, if I add a FormattedWrapper in my component, then it works: class MainScreen extends Component {
render() {
return (
<FormattedWrapper locale={this.props.state.Language.language} messages={messages}>
<ContainerView>
<TitleText text={<FormattedMessage
message="Welcome"/>} />
</ContainerView>
</FormattedWrapper>
);
}
} Same version without the FormattedWrapper: class MainScreen extends Component {
render() {
return (
<ContainerView>
<TitleText text={<FormattedMessage
message="Welcome"/>} />
</ContainerView>
);
}
} Am I doing something wrong? |
I don't see anything super obvious, but I just tried a basic setup loosely based on yours and had no issue. So there must be some issue somewhere in your hierarchy. You definitely shouldn't need to put You can also try putting a test component in to see what the current locale is, i.e. import React, { Component } from 'react';
import { PropTypes as GlobalizePropTypes } from 'react-native-globalize';
import { Text } from 'react-native';
class Test extends Component {
static contextTypes = {
globalize: GlobalizePropTypes.globalizeShape,
}
render() {
return (
<Text>{this.context.globalize.globalize.cldr.locale}</Text>
);
}
}
// The above component will output a Text node with the locale string (e.g. en). Place it somewhere and you can see what's being propagated.
class MainScreen extends Component {
render() {
<ContainerView>
<Test />
</ContainerView>
}
} |
CODE: import React, { Component } from 'react';
import { StatusBar, Platform, Text } from 'react-native';
import { Provider, connect } from 'react-redux';
import { ThemeProvider } from 'styled-components';
import styled from 'styled-components/native';
import { PropTypes as GlobalizePropTypes, FormattedWrapper } from 'react-native-globalize';
import messages from './Messages';
import store from './store';
import Navigator from './Navigator';
import { colors } from './utils/constants';
const Root = styled.View`
flex: 1;
background-color: ${props => props.theme.BACKGROUND_GREY};
`;
const StatusBarAndroid = styled.View`
height: 24;
background-color: ${props => props.theme.HEADER_DARK};
`;
class Test extends Component {
static contextTypes = {
globalize: GlobalizePropTypes.globalizeShape,
}
render() {
console.log("globalize",this.context.globalize.globalize.cldr.locale);
return (
<Text>{this.context.globalize.globalize.cldr.locale}</Text>
);
}
}
class RootContainer extends Component {
render() {
const locale = this.props.locale;
console.log("RootLocale",locale);
return (
<ThemeProvider theme={colors}>
<FormattedWrapper locale={locale} messages={messages}>
<Root>
<StatusBar barStyle='light-content' backgroundColor='transparent' translucent />
{ Platform.OS === 'android' && Platform.Version >= 20 ? <StatusBarAndroid /> : null }
<Test />
<Navigator />
</Root>
</FormattedWrapper>
</ThemeProvider>
);
}
}
const mapStateToProps = (state) => ({
state,
locale: state.Language.language
});
const ConnectedRootContainer = connect(mapStateToProps,null)(RootContainer);
class App extends Component {
render() {
return (
<Provider store={store}>
<ConnectedRootContainer />
</Provider>
);
}
}
export default App; Messages: const messages = {
en: {
Welcome: 'Welcome!!',
Settings: 'Settings'
},
es: {
Welcome: 'Bienvenido',
Settings: 'Configuraciones'
},
};
export default messages; It is in fact changed :) I'm using Expo.io by the way, but the lib should be compatible? :) |
@joshswan By the way, it's an open source boilerplate I'm trying to contribute to: https://github.com/ipeedy/react-native-boilerplate I have gotten my initial version merged, but I would really like to finish it off with the correct change of language :D |
If the locale is propagating correctly, then the issue is probably elsewhere. Try putting the test component in your screen and also try rendering the |
@joshswan It's changed back to "en" right after. The render code for that screen is: render() {
return (
<ContainerView>
<TitleText><FormattedMessage
message="Settings"
/></TitleText>
<Text><FormattedMessage
message="Settings"/></Text>
<FormattedMessage
message="Settings"/>
<Test />
<Button text="Change language to es" onPress={() => {this.props.changeLanguage('es')}} />
</ContainerView>
);
} I really appreciate you trying to help me solve this! Do you have any ideas why this happens? |
I dug into this a bit deeper and the issue here is the use of In the meantime, if you remove the |
Thanks for the update. I'm trying to figure out how it works with adding a component to the top of the stack in React-Navigator. Do you have any input of how to do that? I really think it would be nice, if we could somehow sum up this issue, and add a small "Troubleshoot" part to the README.md :) |
|
@joshswan AWESOME! I have swapped the FormattedWrapper with a FormattedProvider and then it start complaining about context.changedBits. Code: class RootContainer extends Component {
render() {
const locale = this.props.locale;
console.log("RootLocale",locale);
return (
<ThemeProvider theme={colors}>
<FormattedProvider locale={locale} messages={messages}>
<Root>
<StatusBar barStyle='dark-content' backgroundColor='transparent' translucent />
{ Platform.OS === 'android' && Platform.Version >= 20 ? <StatusBarAndroid /> : null }
<Navigator />
</Root>
</FormattedProvider>
</ThemeProvider>
);
}
} App.js:30 is: All dependencies are updated: "dependencies": {
"expo": "26.0.0",
"react": "16.3.1",
"react-native": "github:expo/react-native#sdk-26.0.0",
"react-native-globalize": "2.0.0",
"react-navigation": "1.5.11",
"react-redux": "5.0.7",
"redux": "3.7.2",
"redux-logger": "3.0.6",
"redux-thunk": "2.2.0",
"styled-components": "3.2.5"
} |
React |
For Expo, these are the correct dependency versions: "dependencies": {
"expo": "26.0.0",
"react": "16.3.0-alpha.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-26.0.0.tar.gz",
"react-native-globalize": "2.0.0",
"react-navigation": "1.5.8",
"react-redux": "5.0.7",
"redux": "3.7.2",
"redux-logger": "3.0.6",
"redux-thunk": "2.2.0",
"styled-components": "3.2.5"
} Souce: https://blog.expo.io/expo-sdk-v26-0-0-is-now-available-2be6d9805b31 Thank you so much for you help @joshswan !! The app works so great now! |
Hi,
I can't find a way to change active locale programmatically, I read the doc and issues on github to no luck, maybe I miss something?
Fyi, I have two locales in my App, I can access methods from the context, also with static methods. if I do:
this.context.globalize = new Globalize(alternateLocale);
it seem the locale changed briefly before it revert back (saw the text changed briefly).
The text was updated successfully, but these errors were encountered: