managing internationalization via redux
(see react-pagan
demo)
Include i18n reducer in redux:
import { i18n } from 'redux-pagan';
const createStoreWithMiddleware = applyMiddleware(
thunk
)(createStore);
const rootReducer = combineReducers({
i18n
});
const store = createStoreWithMiddleware(rootReducer);
...
import { loadLang } from 'redux-pagan';
function getLangData(locale) {
// here we use promise-loader to load lang data by demand
return require('promise?global,[name].i18n!json!./i18n/' + locale + '.i18n.json');
}
@connect(...)
class App extends Component {
componentDidMount() {
this.props.dispatch(loadLang(cookie.get('lang') || 'en-US', getLangData));
}
render() {
return (
<select onChange={this.handleLocaleChange}
value={this.props.locale}>
<option value='en-US'>en-US</option>
<option value='ru-RU'>ru-RU</option>
<option value='fi-FI'>fi-FI</option>
</select>
);
}
handleLocaleChange = e => {
this.props.dispatch(loadLang(e.target.value, getLangData));
}
}
getLang(state.i18n, ...path)
is a special method that safely obtains strings from lang data. If no strings were found on stated path, last key is returned. This method's calling is chainable:
getLang(state.i18n, 'some', 'path', 'to')('lang', 'string')
Every call is memoized. To receive string value from last call, use .toString()
or .s
property.
// in this case lang data looks like:
// {
// "app": {
// "some": {
// "text": "foobar"
// },
// "element": {
// "something": {
// "else": "foobar"
// }
// }
// }
// }
import { connect } from 'react-redux';
import { getLang } from 'redux-pagan';
@connect(state => ({
lang: getLang(state.i18n, 'app'),
locale: state.i18n.locale
}))
class App extends Component {
render() {
// string methods are proxied, no need to call .toString() either
const str = this.props.lang('some', 'text').replace('foo', 'bar');
return (
<div>
{this.props.lang('some', 'text').s}
<Element lang={this.props.lang('element').s} />
</div>
);
}
}
class Element extends Component {
render() {
return (
<div>
{this.props.lang('something', 'else').s}
</div>
);
}
}